Анатомия веб-сервиса, Андрей Смирнов (ex-Skype)
description
Transcript of Анатомия веб-сервиса, Андрей Смирнов (ex-Skype)
Анатомиявеб-сервиса 2.0
Андрей Смирнов
Backend
Чем занят backend?
T
- CPU - I/O
Compress 1K bytes with Zippy 3,000 ns Round trip within same datacenter 500,000 ns
h,ps://gist.github.com/jboner/2841832
Роль HTTP reverse proxy• Буферизация запроса
• Буферизация ответа
• “Борьба” с медленными клиентами
• “Снятие” HTTPS
• Отдача статики
Чем занят backend?
1. Склеивание строк
2. Сетевой ввод-вывод
Оптимизация backendа
• Увеличение производительности
• Уменьшение времени отклика
Параллелизм запросов
Параллелизм одного запроса
T
Сетевой ввод-вывод• Блокирующийся
• Неблокирующийся
• Асинхронный
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, timeout) ⇛ ready to read/write
• do read/write until EAGAIN
Многозадачность• Обслуживание нескольких клиентов одновременно
• Цель: минимизировать время отклика при условии максимальной нагрузки
↺
Процессы• Полная* изоляция
• Видимость для планировщика ОС
• Сложность коммуникации
• Использование всех процессоров
Процессыcode
r/o
data
heap
code
r/o
data
heap
fork()
listen() accept()SHM
Примеры• Apache: mod_prefork
• FastCGI
• Phusion Passenger
• PostgreSQL
• …
Нити (ОС)• Видны планировщику
• Имеют отдельный стек и TLS
• Более легковесные, чем процесс
• Отсутствует изоляция
• Сложность написания корректных программ
Синхронизация• Любой доступ к общим данным должен быть синхронизирован
• Атомарные операции (без синхронизации)
• GIL
Примеры• MySQL
• Varnish
• …
Кооперативная многозадачность• “Невидима” для ОС, один процесс (нить)
• “Поток” добровольно передает управление другому (проще синхронизация)
• Явная: callbackи
• Неявная: green threads ↺
Реактор• “Дай мне кучу сокетов, а я сделаю callback, когда они будут готовы”
• Таймер: “Вызови меня через X мс”
Что внутри• Отсортированный по времени срабатывания список таймеров + callback
• Список файловых дескрипторов для ожидания готовности + callback
• select(fds, min(timer)) ⇛ callbacks
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)
Примеры• Redis
• memcached*
• …
Комбинированные варианты• M нитей : N кооперативных потоков
• nginx
• memcached
• …
Драйвер “БД”• База данных
• Очередь
• K-V хранилище
• Другой сервис
• …
Соединение• Соединение:
• на один запрос
• постоянное
TCP Connect Auth Send query Wait Result Disconnect
Send query Wait Result Send query Wait Result
Pipelining• Pipelining запросов
Send query Wait Result Send query Wait Result
Send query Result Send query Result
Proxy
•mcrouter
•twemproxy
•PgBouncer
•…
А что если backend сложнее?• Сервис-ориентированная архитектура
• Очереди, шины, асинхронная обработка задач
• Кеши, конфигурация, …
• …
Реальный мир• А что же происходит в моем любимом языке программирования X?
h,p://www.123freevectors.com/soldier-skull-with-helmet-vector-art/
JavaScript• Однопоточный
• Явная кооперативная многозадачность
• AJAX, Timer, CSS3 Animation, …
• jQuery.Deferred()
PHP• Нет потоков*
• “Начинаем сначала” на каждый запрос
• Потребность в “accelerator”ах
• Персистентные соединения с БД
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, Undertow, …
• Thread Pool
Go• Горутины (goroutines)
• Комбинированный вариант (M:N)
• Неблокирующий ввод-вывод
• Каналы
Erlang• Actor model
• Process - комбинированная модель
• Полная изоляция (обмен данными через коммуникацию)
• Распределенные процессы
Спасибо! Вопросы?• Андрей Смирнов
• @smira
• h,p://smira.ru/