Upload
ontico
View
121
Download
2
Embed Size (px)
Citation preview
Анатомия веб-‐сервиса
Андрей Смирнов
О чем мы будем говорить?• Введение
• Сетевой ввод-‐вывод
• Многозадачность
• Драйвер БД
• Взаимодействие
• Фреймворки
Backend
Чем занят backend?• Склеивание строк
• Сетевой ввод-‐вывод
L1 cache reference 0.5 ns Main memory reference100 ns Read 1 MB sequenRally from network 10,000,000 ns Read 1 MB sequenRally from disk30,000,000 ns
Что делает backend1. Принять соединение (обычно от proxy) и
распарсить HTTP-‐запрос
2. Аутенфикация
3. Авторизация
4. Сессия
Что делает backend5. Распарсить URL, routing
6. Определение формата вывода, rate limiting, …
7. Бизнес-‐логика, выполнение запроса, кеширование
8. Формирование ответа, шаблоны
Сетевой ввод-‐вывод• Блокирующийся
• Неблокирующийся
• Асинхронный
UNIX (POSIX)• fd -‐ файловый дескриптор
• fd = socket()
• listen(fd)/accept(fd)
• read(fd, buf)
• write(fd, buf)
• close(fd)
Блокирующийся ввод-‐вывод• accept(fd) -‐ заблокируется, пока не будет нового входящего соединения
• read(fd, buf) -‐ заблокируется, пока не прибудут данные в сокет
• write(fd, buf) -‐ заблокируется, пока не освободится место в буфере TCP
Неблокирующийся ввод-‐вывод• Любая операция завершается немедленно
• Вместо того, чтобы заблокироваться, вызов возвращает EAGAIN/EWOULDBLOCK
Опрос готовности• Нотификации:
• level-‐triggered (состояние)
• edge-‐triggered (изменение состояния)
• Механизмы:
• select(), poll()
• epoll(), kqueue()
Неблокирующийввод-‐вывод• select(fds, Rmeout) ⇛ ready to read/write
• do read/write unRl EAGAIN
Многозадачность• Обслуживание нескольких клиентов одновременно
• Цель: минимизировать время отклика при условии максимальной нагрузки
Процессы• Полная* изоляция
• Видимость для планировщика ОС
• Сложность коммуникации
• Использование всех процессоров
Процессы
code
r/o
data
heap
code
r/o
data
heap
fork()
listen() accept()SHM
Нити (ОС)• Видны планировщику
• Имеют отдельный стек и TLS
• Более легковесные, чем процесс
• Отсутствует изоляция
• Сложность написания корректных программ
Синхронизация• Любой доступ к общим данным должен быть синхронизирован
• Атомарные операции (без синхронизации)
• GIL
Deadlock
Worker
Event Loop
Кооперативная многозадачность• “Невидима” для ОС, один процесс (нить)
• “Поток” добровольно передает управление другому (проще синхронизация)
• Явная: callbackи
• Неявная: green threads
Реактор• “Дай мне кучу сокетов, а я сделаю callback, когда они будут готовы”
• Таймер: “Вызови меня через X мс”
node.jsvar net = require('net'); var client = net.connect({port: 8124}, function() { //'connect' listener console.log('client connected'); client.write('world!\r\n'); }); client.on('data', function(data) { console.log(data.toString()); client.end(); }); client.on('end', function() { console.log('client disconnected'); });
gevent
def print_head(url):! print('Starting %s' % url)! data = urlopen(url).read()! print('%s: %s bytes: %r' % (url, len(data), data[:50]))!!jobs = [gevent.spawn(print_head, url) for url in urls]!!gevent.wait(jobs)!
Комбинированные варианты• 1:1
• N:1
• M:N
Драйвер “БД”• База данных
• Очередь
• K-‐V хранилище
• Другой сервис
• …
Соединение• Соединение:
• на один запрос • постоянное
TCP!connect Auth Send query Wait Result
Send query Wait Result Send query Wait Result
Disconnect
Pipelining• Pipelining запросов
Send query Wait Result Send query Wait Result
Send query Send query Result Result
Соединения• Кол-‐во соединений:
• одно
• connecRon pool
• по количеству запросов
Proxy
Взаимодействие• Очереди
• вычислительно сложные задачи
• асинхронные действия
• Архитектурное деление на компоненты
• Обращения к другим сервисам
Очередь задач
Очереди• Publish-‐Subcribe vs. Producer-‐Consumer
• Redis, beanstalkd
• pgq
• RabbitMQ
• Apache Ka�a
RPC• Синхронное взаимодействие: запрос-‐ответ
Широковещательная шина
ØMQ• Коммуникационная библиотека
• Без брокера
• Абстракция установления соединения, реконнектов, транспорта и т.п.
• Паттерны обмена сообщениями
Service-‐Oriented Architecture
SOA• Четко выделенные сервисы со своим интерфейсом
• Сервисы независимы
• Сложность эксплуатации
• Независимое масштабирование
Реальный мир• А что же происходит в моем любимом языке программирования X?
JavaScript• Однопоточный
• Явная кооперативная многозадачность
• AJAX, Timer, CSS3 AnimaRon, …
• jQuery.Deferred()
PHP• Нет потоков*
• “Начинаем сначала” на каждый запрос
• Потребность в “accelerator”ах
• Персистентные соединения с БД
FastCGI
Ruby on Rails• Огромное влияние
• Редкие многопоточные применения
• MRI (1.8), YARV (1.9+), JRuby
• Event Machine
• Rack: middleware
Python• WSGI: middleware
• Блокирующий ввод-‐вывод (Django, …)
• Явная кооперативная многозадачность (Twisted, Tornado)
• Корутины (gevent, eventlet, …)
Java• Потоки ОС
• Неблокирующий ввод-‐вывод: NIO, NIO2
• Ne�y
• Thread Pool
Go• Горутины (gorouRnes)
• Комбинированный вариант (M:N)
• Неблокирующий ввод-‐вывод
• Каналы
Erlang• Actor model
• Process -‐ комбинированная модель
• Полная изоляция (обмен данными через коммуникацию)
• Распределенные процессы
© Copyright 2014 Andrey Smirnov
Разработка надежных высоконагруженных систем
• 24, 25 и 26-‐го мая, Москва
• h�p://smira.highload.ru/
• Мастер-‐класс с практическими заданиями