Анатомия

веб-­‐сервиса
Андрей	
  Смирнов
О	
  чем	
  мы	
  будем	
  говорить?
• Введение	
  
• Сетевой	
  ввод-­‐вывод	
  
• Многозадачность	
  
• Драйвер	
  БД	
  
• Взаимодействие	
  
• Фреймворки
Backend
Чем	
  занят	
  backend?
• Склеивание	
  строк	
  
• Сетевой	
  ввод-­‐вывод
L1	
  cache	
  reference	
  

0.5	
  ns	
  
Main	
  memory	
  
reference

100	
  ns	
  
Read	
  1	
  MB	
  sequenRally	
  
from	
  network	
  

10,000,000	
  ns	
  
Read	
  1	
  MB	
  sequenRally	
  
from	
  disk

30,000,000	
  ns
Что	
  делает	
  backend
1. Принять	
  соединение	
  (обычно	
  от	
  proxy)	
  и	
  
распарсить	
  HTTP-­‐запрос	
  
2. Аутенфикация	
  
3. Авторизация	
  
4. Сессия
Что	
  делает	
  backend
5. Распарсить	
  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.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)!
Комбинированные	
  варианты
• 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/	
  
• Мастер-­‐класс	
  с	
  практическими	
  заданиями

Анатомия веб-сервиса, Андрей Смирнов