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

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

Upload: andrey-smirnov

Post on 14-Nov-2014

1.728 views

Category:

Engineering


2 download

DESCRIPTION

 

TRANSCRIPT

Анатомия веб-­‐сервиса

Андрей  Смирнов

О  чем  мы  будем  говорить?• Введение  

• Сетевой  ввод-­‐вывод  

• Многозадачность  

• Драйвер  БД  

• Взаимодействие  

• Фреймворки

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/  

• Мастер-­‐класс  с  практическими  заданиями