Ilia kantor паттерны серверных comet решений
Upcoming SlideShare
Loading in...5
×
 

Ilia kantor паттерны серверных comet решений

on

  • 1,620 views

 

Statistics

Views

Total Views
1,620
Views on SlideShare
1,451
Embed Views
169

Actions

Likes
1
Downloads
18
Comments
0

8 Embeds 169

http://profyclub.ru 114
http://new.profyclub.ru 20
http://profyclub.ontico.ru 12
http://ritconf.ru 11
http://www.slideshare.net 6
http://www.ritconf.ru 4
http://rit-conf.org 1
http://2011.ritconf.ru 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Ilia kantor паттерны серверных comet решений Ilia kantor паттерны серверных comet решений Presentation Transcript

  • ПаттерныСерверных COMET-решений
    Илья Кантор
    http://javascript.ru
  • Классические серверные паттерны
    Процессы OS
    процессы
    // инициализация фреймворка
    includeMyFramework;
    MyFramework::init();
    db=DB::connect();
    // while ждеточереднойзапрос
    while(request=FastCGI::accept()){
    MyFramework::process(request);
    }
    MyFramework::finalize();
    Раздельное
    адресное
    пространство
  • Классические серверные паттерны
    Процессы OS
    Pre-fork
    Обмен данными
    Shared memory
    Переменные процесса
    процессы
    Shared memory
    while
    MyFramework::init();
    db=DB::connect();
    while(accept…){

    }
    • данные (строки)
    • очереди
    • синхронизация
  • Классические серверные паттерны
    Потоки OS
    пул потоков
    объект MyServlet
    потоки
    Общее
    адресное
    пространство
    publicclassMyServletextendsHttpServlet{
    privateUsercurrentUser;
    publicvoiddoGet(…req,…resp){
    currentUser=authorizeUser(req);
    // ...
    resp.getWriter().println(currentUser)
    }
    }
    doGet
  • Классические серверные паттерны
    Потоки OS
    запросы
    1
    2
    publicclassMyServletextendsHttpServlet{
    privateUsercurrentUser;
    publicvoiddoGet(HttpServletRequestreq,HttpServletResponseresp){
    currentUser=authorizeUser(req);
    // ...
    resp.getWriter().println(currentUser)
    }
    }
    Петя
    Вася
    Петя
    Петя
    ошибка
  • Сравнение
  • Гибридные паттерны
    Процессы + потоки
    Несколько процессов (Worker MPM)
    В каждом процессе много потоков
    Увеличенная надежность
    Event MPM
    отдельный поток для Keep-Alive
    позволяет «рабочим» потокам работать дальше, пока висит Keep-Alive
  • COMET
    Long Poll
    Разрыв связи
    Конец запроса
    Разрыв связи
    Конец запроса
    t
    Соединение
    не закрывается
    Соединение
    не закрывается
    данные
    запрос
    данные
    запрос
    запрос
  • COMET
    Streaming
    Разрыв связи
    Конец запроса
    t
    Соединение не закрывается
    данные
    запрос
    данные
    данные
    запрос
  • Сравнение
    Обычный цикл
    Принять запрос
    Сгенерировать страничку
    Выдать страницу
  • Сравнение
    COMET
    Принять запрос
    • посетитель подключился
    • ждать события
    Сгенерировать ответ
    Выдать ответ
    Особенности
    • Большое количество ожидающих соединений
    • Потоки/процессы съедают ресурсы
    • Активная межпроцессная коммуникация
    • Небольшой размер ответа
  • События в едином потоке
    Twisted, node.js
    все действия, которые требуют ожидания, совершаются асинхронно
    simple.py
    dbpool=adbapi.ConnectionPool("MySQLdb",host="localhost",db="test”)
    classMyResource(resource.Resource):
    deflogin(self,result,request):
    ifresult: request.write("Привет, %s! Твой ID:%d"%result[0])
    else: request.write("Я Вас не знаю!")
    request.finish()
    defrender_GET(self,request):
    name=request.args['name']
    deferred=dbpool.runQuery("SELECT * FROM users WHERE name = '%s' "%name)
    deferred.addCallback(lambdaresult:self.login(result,request))
    returnserver.NOT_DONE_YET
  • Модель работы
    classMyResource(resource.Resource):
    deflogin(self,result,request):
    request.write(“…"%result)
    request.finish()
    defrender_GET(self,request):
    name=request.args['name']
    deferred=dbpool.runQuery("…"%name)
    deferred.addCallback(self.login)
    returnserver.NOT_DONE_YET
    Twistd
    пул потоков
    render_GET
  • Общие данные
    Пример COMET-приложения
    comet.pycomet.js
    все клиенты в одном массиве
    Twistd
    classClientManager:
    clients=[]
    defregisterClient(self,client):
    self.clients.append(client)
    defbroadcastMessage(self,message):
    forclientinself.clients:
    client.write(message)
    client.finish()
    self.clients=[]
  • Характеристики метода
    Для удобного асинхронного вызова нужно Async API
    Хорошо когда оно есть
    Плохо, что оно не всегда есть
    Нет синхронизации
    Основной процесс использует только 1 ядро
    Что делать при 100% загрузке CPU?
    Выделять сложные операции в потоки (Python – GIL, сетевые операции не thread-safe)
    Запускать несколько экземпляров (процессов) сервера (данные не в едином адресном пространстве)
  • Почитать
    Twisted
    Официальная документация и учебник
    Twisted.Web In 60 Seconds
    Node.js
    nodejs.ru
    Streaming file uploads with node.js
  • Continuations(Jetty, GlassFish…)
    Запрос 1 ожидает сообщение
    1
    publicclassSubscribeServletextendsHttpServlet{
    protectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp){
    }
    // 1. запрос «упаковывается» в объект continuation
    Continuationcontinuation=ContinuationSupport.getContinuation(req);
    if(continuation.isInitial()){ // true
    // 2. сообщить серверу, что запрос неокончен
    continuation.suspend();
    }
    // 3. передать continuation асинхронному обработчику
    ClientManager.getInstance().registerClient(continuation);
    Continuation (неоконченный запрос)
    «подвис» на сервере
  • Continuations
    Запрос 2 инициирует событие
    2
    publicclassClientManager{
    // 1. массив клиентов / запросов
    ArrayList<Continuation>continuations=newArrayList<Continuation>();
    publicsynchronizedvoidbroadcastMessage(Stringmessage){
    for(Continuationcontinuation:continuations){
    }
    }
    }
    // 2. передать информациюо событии в continuation
    continuation.setAttribute("message",message);
    // 3. попросить сервер продолжить обработку
    continuation.resume();
    можно в цикле выдавать ответы в запросы
  • Continuations
    Сервер перезапускает запрос 1
    1
    1(2)
    publicclassSubscribeServletextendsHttpServlet{
    protectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp){
    }
    // 1(2).возвратит объект сontinuation, соответствующий запросу
    Continuationcontinuation=ContinuationSupport.getContinuation(req);
    if(continuation.isInitial()){ // true
    // 1(1). сообщить серверу, что запрос неокончен
    continuation.suspend();
    }else{
    }
    // false
    // 1(1). передать continuation асинхронному обработчику
    ClientManager.getInstance().registerClient(continuation);
    Stringmessage=(String)continuation.getAttribute("message");
    resp.getWriter().print(message);
  • Характеристики метода
    Основан на потоках
    Используются все ядра
    Синхронизация, многопоточное программирование
    Многопоточная обработка оживших continuations
    publicsynchronizedvoidbroadcastMessage
    for(Continuationcontinuation:continuations){
    // разбросает обработку continuations по потокам
    continuation.resume()
    }
  • Почитать
    Continuations to Continue
    Continuations (статья старовата)
    JSR-000315 JavaServlet 3.0 (Спецификация)
    Glassfish
  • Микронити
    Erlang, Stackless Python, …
    Предыдущие подходы:
    Сохранить запрос в памяти и освободить поток для нового запроса
    Микронити:
    Сделать поток максимально «легким» - и можно не освобождать
    Решение: отказ от потоков и стека OS, свои потоки
  • Микронити
    chat_web.erl
  • Почитать
    A Million-user Comet Application with Mochiweb: Part 1, Part 2, Part 3
    Building an Erlang chat server with Comet: Part1, Part 2, Part 3
    Comet web chat (with MochiWeb)
    Using the mochiweb project skeleton
    Mochiweb source
    Документация к API
    Erlang
    Официальный сайт
    Erlang in Practice(screencast)