0
ПаттерныСерверных COMET-решений<br />Илья Кантор<br />http://javascript.ru<br />
Классические серверные паттерны<br />Процессы OS<br />процессы<br />// инициализация фреймворка<br />includeMyFramework;<b...
Классические серверные паттерны<br />Процессы OS<br />Pre-fork<br />Обмен данными<br />Shared memory<br />Переменные проце...
очереди
синхронизация</li></li></ul><li>Классические серверные паттерны<br />Потоки OS<br />пул потоков<br />объект MyServlet<br /...
Классические серверные паттерны<br />Потоки OS<br />запросы<br />1<br />2<br />publicclassMyServletextendsHttpServlet{<br ...
Сравнение<br />
Гибридные паттерны<br />Процессы + потоки<br />Несколько процессов (Worker MPM)<br />В каждом процессе много потоков<br />...
COMET<br />Long Poll<br />Разрыв связи<br />Конец запроса<br />Разрыв связи<br />Конец запроса<br />t<br />Соединение <br ...
COMET<br />Streaming<br />Разрыв связи<br />Конец запроса<br />t<br />Соединение не закрывается<br />данные<br />запрос<br...
Сравнение<br />Обычный цикл<br />Принять запрос<br />Сгенерировать страничку<br />Выдать страницу<br />
Сравнение<br />           COMET<br />Принять запрос <br /><ul><li>посетитель подключился
ждать события</li></ul>Сгенерировать ответ<br />Выдать ответ<br />Особенности<br /><ul><li>Большое количество ожидающих со...
Потоки/процессы съедают ресурсы
Активная межпроцессная коммуникация
Небольшой размер ответа</li></li></ul><li>События в едином потоке<br />Twisted, node.js<br />все действия, которые требуют...
Модель работы<br />classMyResource(resource.Resource):<br />    deflogin(self,result,request):<br />request.write(“…"%resu...
Общие данные<br />Пример COMET-приложения<br />comet.pycomet.js<br />все клиенты в одном массиве<br />Twistd<br />classCli...
Характеристики метода<br />Для удобного асинхронного вызова нужно Async API<br />Хорошо когда оно есть<br />Плохо, что оно...
Почитать<br />Twisted<br />Официальная документация и учебник<br />Twisted.Web In 60 Seconds<br />Node.js<br />nodejs.ru<b...
Continuations(Jetty, GlassFish…)<br />Запрос 1 ожидает сообщение <br />1<br />publicclassSubscribeServletextendsHttpServle...
Continuations <br />Запрос 2 инициирует событие<br />2<br />publicclassClientManager{<br />// 1. массив клиентов / запросо...
Continuations <br />Сервер перезапускает запрос 1<br />1<br />1(2)<br />publicclassSubscribeServletextendsHttpServlet{<br ...
Характеристики метода<br />Основан на потоках<br />Используются все ядра<br />Синхронизация, многопоточное программировани...
Upcoming SlideShare
Loading in...5
×

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

1,237

Published on

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,237
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
19
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

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

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

    Clipping is a handy way to collect important slides you want to go back to later.

×