Анатомия 
веб-сервиса 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.js 
var 
net 
= 
require('net'); 
var 
client 
= 
net.connect({port: 
8124}, 
function() 
{ 
//'connect' 
listener 
console.log('client 
connected'); 
client.write('world!rn'); 
}); 
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
.NET 
• Потоки ОС 
• async/await 
• ASP.NET, ServiceStack, Nancy, … 
• Mono
Go 
• Горутины (goroutines) 
• Комбинированный вариант (M:N) 
• Неблокирующий ввод-вывод 
• Каналы
Erlang 
• Actor model 
• Process - комбинированная модель 
• Полная изоляция (обмен данными через 
коммуникацию) 
• Распределенные процессы
Спасибо! Вопросы? 
• Андрей Смирнов 
• @smira 
• me@smira.ru 
• h,p://smira.ru/

Анатомия веб сервиса (HighLoad-2014)

  • 1.
    Анатомия веб-сервиса 2.0 Андрей Смирнов
  • 2.
  • 3.
    Чем занят 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
  • 4.
    Роль HTTP reverseproxy • Буферизация запроса • Буферизация ответа • “Борьба” с медленными клиентами • “Снятие” HTTPS • Отдача статики
  • 5.
    Чем занят backend? 1. Склеивание строк 2. Сетевой ввод-вывод
  • 6.
    Оптимизация backendа •Увеличение производительности • Уменьшение времени отклика
  • 7.
  • 8.
  • 9.
    Сетевой ввод-вывод •Блокирующийся • Неблокирующийся • Асинхронный
  • 10.
    UNIX (POSIX) •fd - файловый дескриптор • fd = socket() • listen(fd)/accept(fd) • read(fd, buf) • write(fd, buf) • close(fd)
  • 11.
    Блокирующийся ввод-вывод •accept(fd) - заблокируется, пока не будет нового входящего соединения • read(fd, buf) - заблокируется, пока не прибудут данные в сокет • write(fd, buf) - заблокируется, пока не освободится место в буфере TCP
  • 12.
    Неблокирующийся ввод-вывод •Любая операция завершается немедленно • Вместо того, чтобы заблокироваться, вызов возвращает EAGAIN/EWOULDBLOCK
  • 13.
    Опрос готовности •Нотификации: • level-triggered (состояние) • edge-triggered (изменение состояния) • Механизмы: • select(), poll() • epoll(), kqueue()
  • 14.
    Неблокирующий ввод-вывод •select(fds, timeout) ⇛ ready to read/write • do read/write until EAGAIN
  • 15.
    Многозадачность • Обслуживаниенескольких клиентов одновременно • Цель: минимизировать время отклика при условии максимальной нагрузки ↺
  • 16.
    Процессы • Полная*изоляция • Видимость для планировщика ОС • Сложность коммуникации • Использование всех процессоров
  • 17.
    Процессы code r/o data heap code r/o data heap fork() listen() accept() SHM
  • 18.
    Примеры • Apache:mod_prefork • FastCGI • Phusion Passenger • PostgreSQL • …
  • 19.
    Нити (ОС) •Видны планировщику • Имеют отдельный стек и TLS • Более легковесные, чем процесс • Отсутствует изоляция • Сложность написания корректных программ
  • 20.
    Синхронизация • Любойдоступ к общим данным должен быть синхронизирован • Атомарные операции (без синхронизации) • GIL
  • 21.
    Примеры • MySQL • Varnish • …
  • 22.
    Кооперативная многозадачность •“Невидима” для ОС, один процесс (нить) • “Поток” добровольно передает управление другому (проще синхронизация) • Явная: callbackи • Неявная: green threads ↺
  • 23.
    Реактор • “Даймне кучу сокетов, а я сделаю callback, когда они будут готовы” • Таймер: “Вызови меня через X мс”
  • 24.
    Что внутри •Отсортированный по времени срабатывания список таймеров + callback • Список файловых дескрипторов для ожидания готовности + callback • select(fds, min(timer)) ⇛ callbacks
  • 25.
    node.js var net = require('net'); var client = net.connect({port: 8124}, function() { //'connect' listener console.log('client connected'); client.write('world!rn'); }); client.on('data', function(data) { console.log(data.toString()); client.end(); }); client.on('end', function() { console.log('client disconnected'); });
  • 26.
    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)
  • 27.
    Примеры • Redis • memcached* • …
  • 28.
    Комбинированные варианты •M нитей : N кооперативных потоков • nginx • memcached • …
  • 29.
    Драйвер “БД” •База данных • Очередь • K-V хранилище • Другой сервис • …
  • 31.
    Соединение • Соединение: • на один запрос TCP Connect Auth Send query Wait Result Disconnect • постоянное Send query Wait Result Send query Wait Result
  • 32.
    Pipelining • Pipeliningзапросов Send query Wait Result Send query Wait Result Send query Result Send query Result
  • 33.
    Proxy •mcrouter •twemproxy •PgBouncer •…
  • 34.
    А что еслиbackend сложнее? • Сервис-ориентированная архитектура • Очереди, шины, асинхронная обработка задач • Кеши, конфигурация, … • …
  • 35.
    Реальный мир •А что же происходит в моем любимом языке программирования X? h,p://www.123freevectors.com/soldier-skull-with-helmet-vector-art/
  • 36.
    JavaScript • Однопоточный • Явная кооперативная многозадачность • AJAX, Timer, CSS3 Animation, … • jQuery.Deferred()
  • 37.
    PHP • Нетпотоков* • “Начинаем сначала” на каждый запрос • Потребность в “accelerator”ах • Персистентные соединения с БД
  • 38.
    Ruby on Rails • Огромное влияние • Редкие многопоточные применения • MRI (1.8), YARV (1.9+), JRuby • Event Machine • Rack: middleware
  • 39.
    Python • WSGI:middleware • Блокирующий ввод-вывод (Django, …) • Явная кооперативная многозадачность (Twisted, Tornado) • Корутины (gevent, eventlet, …)
  • 40.
    Java • ПотокиОС • Неблокирующий ввод-вывод: NIO, NIO2 • Ne,y, Undertow, … • Thread Pool
  • 41.
    .NET • ПотокиОС • async/await • ASP.NET, ServiceStack, Nancy, … • Mono
  • 42.
    Go • Горутины(goroutines) • Комбинированный вариант (M:N) • Неблокирующий ввод-вывод • Каналы
  • 43.
    Erlang • Actormodel • Process - комбинированная модель • Полная изоляция (обмен данными через коммуникацию) • Распределенные процессы
  • 44.
    Спасибо! Вопросы? •Андрей Смирнов • @smira • me@smira.ru • h,p://smira.ru/