SlideShare uma empresa Scribd logo
1 de 34
Baixar para ler offline
Асинхронное
программирование в
Python
Проблема C10K
• Условное название задачи конфигурирования и
обслуживания высокопроизводительного
сервера
• Сервер должен быть способен обслуживать
порядка 10 тыс. соединений одновременно
Проблема C10K
• Решение №1
• Поток на каждого клиента
• Решение №2
• Поток на несколько клиентов
Сервера, выдерживающие
проблему
• nginx, which relies on an event-driven (asynchronous) architecture, instead
of threads, to handle requests
• Lighttpd, which relies on an asynchronous architecture to handle requests
• Tornado, a non-blocking web server and web application framework
written in Python (used by Facebook's FriendFeed)
• Apache AWF (retired, formerly Apache Deft), asynchronous, non-blocking
web server running on the JVM
• JBoss Netty, a NIO client server framework which enables quick and easy
development of network applications such as protocol servers and clients
• Node.js, asynchronous, non-blocking web server running on Google's V8
JavaScript engine
Сервера, выдерживающие
проблему
• EventMachine, an asynchronous, non-blocking web
server running on Ruby EventMachine
• Cowboy (web server), another very lightweight web
server written in Erlang
• asyncore (in the standard Python library), a non-
blocking web server library. It is based on Medusa,
which is no longer maintained.
• Django, some research is being done using the
asynchronous IO support in Python 3.3
sync VS async
Sync
• Делится на однопоточную и многопоточную.
Sync: 1 thread
• В однопоточной модели каждая задача
выполняется последовательно. Поток выполняет
следующую задачу только тогда, когда
предыдущая точно завершилась.
Sync: N threads
• В многопоточной модели можно достичь
некоторой "одновременной работы" задач, но на
каждую задачу выделяется один поток. Деталями
управления в многопоточной синхронной модели
управляет ОС.
Async
• Асинхронная модель всегда будет чередовать
выполнение задач. Взаимодействие задач (их
синхронизация) лежит на ответственности
программиста.
sync VS async
• По сравнению с синхронной моделью, асинхронная
модель лучше когда:
1. Когда есть много задач таких, что почти всегда есть по
меньшей мере одна задача, которая может выполняться.
2. Задачи выполняют много операций ввода-вывода,
приводя к тому, что синхронная задача проводит много
времени впустую, блокируясь, в то время когда другие
задачи могли бы выполняться.
3. Задачи независимы друг от друга и не нуждаются во
взаимодействии.
Event-driven programming
• Событийно-ориентированное программирование
• Способ построения программы
• В коде явным образом выделяется главный цикл
приложения
• Тело главного цикла состоит из двух частей:
выборки события и обработки события.
Reactor
• Для ожидания задач и
управления ими, используется
внешний цикл, который
постоянно ждет каких-либо
действий.
• При возникновении задачи, он
немедленно реагирует.
• Каждая задача должна быть в
не блокирующем режиме. какой смысл использовать реактор, если мы
будем блокировать наш внешний цикл, который
как раз и следит за приходом новых задач или
выполнением следующих
Async-servers in Python
• Name Lic. Doc Ex. Prod. Com. Act. Blog Twt Rep. Pool Wsgi Scket Cmet Epoll Test Style
• Twisted! MIT! Yes! Yes! Yes! Huge! Yes! Lots! No! Trac! Yes! Yes! Yes! No! Yes! Yes! Callback!
• Tornado! Apache! Yes! Yes! F.Feed!Yes! Yes! FB! Yes! GHub! No! Lim.! Yes! No! Yes! No!
Async!
• Orbited MIT Yes Yes Yes Yes Yes Yes No Trac No No Yes Yes Yes Yes Callback
• DieselWeb BSD Yes Yes STalk Yes Yes Yes Yes BitB. No Lim. Yes Yes Yes No Generator
• MultiTask MIT Some No No No No Yes No Bzr No No No No No No Generator
• Chiral GPL2 API No No IRC No No No Trac No Yes Yes Yes Yes Yes Coroutine
• Eventlet! MIT! Yes! Yes! S. Life! Yes! Yes! Yes! No! BitB.! Yes! Yes! Yes! No! Yes! Yes! Greenlet!
• FriendlyFlow GPL2 Some One No No No No Yes Ggle No No Yes No No Yes
Generator
• Weightless GPL2 Yes No Yes No No No Yes SF No No Yes No No Yes Generator
• Fibra MIT No No No No No Yes No Ggle No No Yes No No No Generator
• Concurrence! MIT! Yes! Yes! hyves!Yes! Yes! No! No! GHub! No! Yes! Yes! No! Yes! Yes!
Tasklet!
• Circuits MIT Yes Yes Yes Yes Yes Yes Yes Trac No Yes Yes No No Yes Async
http://nichol.as/asynchronous-servers-in-python
Async-servers in Python
• What License does the framework have?
• Does it provide documentation?
• Does the documentation contain examples?
• Is it used in production somewhere?
• Does it have some sort of community (mailinglist, irc, etc..)?
• Is there any recent activity?
• Does it have a blog (from the owner)?
• Does it have a twitter account?
• Where can i find the repository?
• Does it have a Thread Pool?
• Does it provide access to a TCP Socket?
• Does it have any Comet features?
• Is it using EPOLL?
• What kind of server is it? (greenlets, callbacks, generators etc..)
http://nichol.as/asynchronous-servers-in-python
Tornado
• Расширяемый, неблокирующий веб-сервер и
фреймворк, написанный на Python.
• Создан для использования в проекте FriendFeed;
компания была приобретена Facebook в 2009
году и после этого были открыты исходные коды
Tornado.
Tornado
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import logging
from tornado.options import define, options
!
define("port", default=8888, help="run on the given port", type=int)
!
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world!")
!
def main():
tornado.options.parse_command_line()
application = tornado.web.Application([
(r"/", MainHandler),
])
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
!
if __name__ == "__main__":
main()
http://programmingzen.com/2009/09/13/benchmarking-tornado-vs-twisted-web-vs-tornado-on-twisted/
Twisted
• Проекты на Twisted могут поддерживать TCP,
UDP, SSL/TLS, IP Multicast, Unix domain sockets,
большое количество протоколов, включая HTTP,
XMPP, NNTP, IMAP, SSH, IRC, FTP и другие.
• Основан на парадигме событийно-
ориентированного программирования, и это
значит, что пользователи Twisted пишут
небольшие программы обратного вызова,
которые вызываются фреймворком.
Twisted
from twisted.internet import epollreactor
epollreactor.install()
from twisted.internet import reactor
from twisted.web import server, resource
!
!
class Simple(resource.Resource):
isLeaf = True
def render_GET(self, request):
return "Hello, world!"
!
!
site = server.Site(Simple())
reactor.listenTCP(8888, site)
reactor.run()
http://programmingzen.com/2009/09/13/benchmarking-tornado-vs-twisted-web-vs-tornado-on-twisted/
Чуть больше о
Twisted
Twisted
• Шаблон реактор - однопоточный.
• Twisted сам реализует цикл реактора, мы сами не должны
его реализовывать.
• При написании кода, нужно продумывать основную логику
задачи.
• Цикл реактора вызывает наш код в тот момент, когда мы об
этом сами скажем. Реактор наперед не может знать, какую
часть кода нужно вызвать.
• Когда наши callback’и выполняются, цикл реактора не
выполняется, и наоборот.
• После возврата из callback'а, цикл реактора возобновляется
Что делать с
исключениями?
Errbacks
• Реактор не обрабатывает исключения, потому что
ничего о них не знает.
• Реактор -- низкоуровневый метод, а исключения
генерируются из более высокоуровневого кода.
Sync VS Async
1. Синхронный код:!
try:!
text = run_print()!
except Exception, err:!
print err!
sys.exit()!
else:!
print text!
sys.exit()!
!
!
2. Асинхронный код:!
def print_ok(text):!
print text!
reactor.stop()!
!
def print_fail(err):!
print >>sys.stderr, err!
reactor.stop()!
!
run_print(print_ok, print_err)!
!
reactor.run()
Deferred
from twisted.internet.defer import Deferred!
!
def print_ok(text):!
print text!
!
def print_fail(err):!
print >>sys.stderr, err!
!
d = Deferred()!
d.addCallbacks(print_ok, print_fail)!
d.callback("Text is correct") !
# или d.errback(Exception('I have failed.'))!
print "End."!
!
reactor.run()
Deferred
Сервер на Twisted
from twisted.internet import reactor!
from twisted.internet.protocol import ServerFactory !
from twisted.protocols.basic import LineOnlyReceiver !
!
class ChatProtocol(LineOnlyReceiver): !
!
name = "" !
def getName(self): !
if self.name!="": !
return self.name !
return self.transport.getPeer().host !
!
def connectionMade(self): !
print "New connection from "+self.getName() !
self.sendLine("Welcome to my my chat server.") !
self.sendLine("Send '/NAME [new name]' to change your name.") !
self.sendLine("Send '/EXIT' to quit.") !
self.factory.sendMessageToAllClients(self.getName()+" has joined the party.") !
self.factory.clientProtocols.append(self)
Сервер на Twisted
!
!
def connectionLost(self, reason): !
print "Lost connection from "+self.getName() !
self.factory.clientProtocols.remove(self) !
self.factory.sendMessageToAllClients(self.getName()+" has disconnected.") !
!
def lineReceived(self, line): !
print self.getName()+" said "+line !
if line[:5]=="/NAME": !
oldName = self.getName() !
self.name = line[5:].strip() !
self.factory.sendMessageToAllClients(oldName+" changed name !
! ! ! ! to "+self.getName()) !
elif line=="/EXIT": !
self.transport.loseConnection() !
else: !
self.factory.sendMessageToAllClients(self.getName()+" says "+line) !
!
def sendLine(self, line): !
self.transport.write(line+"rn") !
!
Сервер на Twisted
class ChatProtocolFactory(ServerFactory): !
!
protocol = ChatProtocol !
!
def __init__(self): !
self.clientProtocols = [] !
!
def sendMessageToAllClients(self, mesg): !
for client in self.clientProtocols:!
client.sendLine(mesg) !
!
print "Starting Server"!
factory = ChatProtocolFactory()!
reactor.listenTCP(12345, factory)!
reactor.run()!
В качестве клиента: telnet localhost 12345
Async I/O for Python 3
• Пишем асинхронный код без тредов и коллбеков
• Сопрограмма (англ. coroutine) — компонент
программы, обобщающий понятие
подпрограммы, который дополнительно
поддерживает множество входных точек (а не
одну как подпрограмма) и остановку и
продолжение выполнения с сохранением
определённого положения.
Yield from
!
!
class BinaryTree_ForLoop:!
def __init__(self, left=None,
us=None, right=None):!
self.left = left!
self.us = us!
self.right = right!
!
def __iter__(self):!
if self.left:!
for node in self.left:!
yield node!
if self.us:!
yield self.us!
if self.right:!
for node in self.right:!
yield node!
class BinaryTree:!
def __init__(self, !
left=None, us=None, right=None):!
self.left = left!
self.us = us!
self.right = right!
!
def __iter__(self):!
if self.left:!
yield from self.left!
if self.us:!
yield self.us!
if self.right:!
yield from self.right!
!
# For comparison, here is the same thing using for-loops!
# instead of yield-from.
Tulip VS Twisted
import tulip!
from tulip import http!
!
@tulip.coroutine!
def download(url):!
response = yield from http.request('GET', url)!
for k, v in response.items():!
print('{}: {}'.format(k, v[:80]))!
!
data = yield from response.read()!
print('nReceived {} bytes.n'.format(len(data)))!
!
if __name__ == '__main__':!
loop = tulip.get_event_loop()!
coroutine = download('http://omegafeihong.tumblr.com')!
loop.run_until_complete(coroutine)
Tulip VS Twisted
from twisted.internet import reactor!
from twisted.internet.defer import Deferred, succeed!
from twisted.internet.protocol import Protocol!
from twisted.web.client import Agent!
!
def print_headers(response):!
for k, v in response.headers.getAllRawHeaders():!
print('{}: {}'.format(k, v[0][:80]))!
!
return get_response_body(response)!
!
def get_response_body(response):!
class BodyReceiver(Protocol):!
def dataReceived(self, data):!
chunks.append(data)!
def connectionLost(self, reason):!
finished.callback(''.join(chunks))!
!
finished = Deferred()!
chunks = []!
response.deliverBody(BodyReceiver())!
return finished!
!
def print_body(data):!
print('nReceived {} bytes.n'.format(len(data)))!
return succeed(None)!
!
if __name__ == '__main__':!
agent = Agent(reactor)!
d = agent.request('GET', 'http://megafei
d.addCallback(print_headers)!
d.addCallback(print_body)!
d.addCallback(lambda x: reactor.stop())!
reactor.run()
Почитать
• http://ninaevseenko.github.io/async_twisted_ru/async_twisted_ru.pdf
• http://legacy.python.org/dev/peps/pep-3156/#abstract
• http://moscowdjango.ru/meetup/18/tulip/
• http://neednourishment.blogspot.ru
• http://www.ibm.com/developerworks/ru/library/l-python_part_10/index.html
• http://www.slideshare.net/Smirnov.Andrey/twisted-framework-python-2211313
• http://moscowdjango.ru/meetup/14/gil-and-python-why/
• http://legacy.python.org/dev/peps/pep-0380/
• http://legacy.python.org/dev/peps/pep-3156/#event-loop-classes
• http://ru.wikipedia.org/wiki/%D1%EE%E1%FB%F2%E8%E9%ED%EE-%EE%F0%E8%E5%ED%F2%E8%F0%EE%E2%E0%ED
%ED%EE%E5_%EF%F0%EE%E3%F0%E0%EC%EC%E8%F0%EE%E2%E0%ED%E8%E5
• http://nichol.as/asynchronous-servers-in-python
• http://programmingzen.com/2009/09/13/benchmarking-tornado-vs-twisted-web-vs-tornado-on-twisted/
• http://www.slideshare.net/megafeihong/tulip-24190096
• http://www.dabeaz.com/coroutines/

Mais conteúdo relacionado

Mais procurados

Андрей Акиньшин
Андрей АкиньшинАндрей Акиньшин
Андрей АкиньшинCodeFest
 
«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк
«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк
«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банкit-people
 
Введение в Akka
Введение в AkkaВведение в Akka
Введение в AkkaZheka Kozlov
 
Тестирование через мониторинг или холакратия на практике / Максим Чистяков (U...
Тестирование через мониторинг или холакратия на практике / Максим Чистяков (U...Тестирование через мониторинг или холакратия на практике / Максим Чистяков (U...
Тестирование через мониторинг или холакратия на практике / Максим Чистяков (U...Ontico
 
Производительность WebGL-приложений / Дмитренко Кирилл (Яндекс)
Производительность WebGL-приложений / Дмитренко Кирилл (Яндекс)Производительность WebGL-приложений / Дмитренко Кирилл (Яндекс)
Производительность WebGL-приложений / Дмитренко Кирилл (Яндекс)Ontico
 
Отладка производительности приложения на Erlang / Максим Лапшин (Erlyvideo)
 Отладка производительности приложения на Erlang / Максим Лапшин (Erlyvideo) Отладка производительности приложения на Erlang / Максим Лапшин (Erlyvideo)
Отладка производительности приложения на Erlang / Максим Лапшин (Erlyvideo)Ontico
 
Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)
Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)
Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)Ontico
 
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)Ontico
 
Aviasales: миграция поискового движка в docker / Дмитрий Кузьменков (Aviasales)
Aviasales: миграция поискового движка в docker / Дмитрий Кузьменков (Aviasales)Aviasales: миграция поискового движка в docker / Дмитрий Кузьменков (Aviasales)
Aviasales: миграция поискового движка в docker / Дмитрий Кузьменков (Aviasales)Ontico
 
Юрий Насретдинов, Badoo
Юрий Насретдинов, BadooЮрий Насретдинов, Badoo
Юрий Насретдинов, BadooOntico
 
Анатомия веб-сервиса (РИТ-2014)
Анатомия веб-сервиса (РИТ-2014)Анатомия веб-сервиса (РИТ-2014)
Анатомия веб-сервиса (РИТ-2014)Andrey Smirnov
 
Алексей Фомкин, Практическое применение Web Workers
Алексей Фомкин, Практическое применение Web WorkersАлексей Фомкин, Практическое применение Web Workers
Алексей Фомкин, Практическое применение Web WorkersAleksey Fomkin
 
"Fault tolerant workflow orchestration on PHP", Anton Tsitou
"Fault tolerant workflow orchestration on PHP", Anton Tsitou"Fault tolerant workflow orchestration on PHP", Anton Tsitou
"Fault tolerant workflow orchestration on PHP", Anton TsitouFwdays
 
Практика разработки веб-серверов на Rust
Практика разработки веб-серверов на RustПрактика разработки веб-серверов на Rust
Практика разработки веб-серверов на RustMichael Pankov
 
Akka: как я перестал бояться и полюбил асинхронный код
Akka: как я перестал бояться и полюбил асинхронный кодAkka: как я перестал бояться и полюбил асинхронный код
Akka: как я перестал бояться и полюбил асинхронный кодRoman Grebennikov
 
«Write once run anywhere — почём опиум для народа?» Игорь Новиков, Scalr
«Write once run anywhere — почём опиум для народа?» Игорь Новиков, Scalr«Write once run anywhere — почём опиум для народа?» Игорь Новиков, Scalr
«Write once run anywhere — почём опиум для народа?» Игорь Новиков, Scalrit-people
 
«Тотальный контроль производительности» Михаил Юматов, ЦИАН
«Тотальный контроль производительности» Михаил Юматов, ЦИАН«Тотальный контроль производительности» Михаил Юматов, ЦИАН
«Тотальный контроль производительности» Михаил Юматов, ЦИАНit-people
 
Денис Иванов
Денис ИвановДенис Иванов
Денис ИвановCodeFest
 
Путь к Go на конкретном примере
Путь к Go на конкретном примереПуть к Go на конкретном примере
Путь к Go на конкретном примереSergey Xek
 
Оптимизация производительности фронтенда / Игорь Алексеенко (HTML Academy)
Оптимизация производительности фронтенда / Игорь Алексеенко (HTML Academy)Оптимизация производительности фронтенда / Игорь Алексеенко (HTML Academy)
Оптимизация производительности фронтенда / Игорь Алексеенко (HTML Academy)Ontico
 

Mais procurados (20)

Андрей Акиньшин
Андрей АкиньшинАндрей Акиньшин
Андрей Акиньшин
 
«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк
«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк
«Детские болезни live-чата» Ольга Сентемова, Тинькофф Банк
 
Введение в Akka
Введение в AkkaВведение в Akka
Введение в Akka
 
Тестирование через мониторинг или холакратия на практике / Максим Чистяков (U...
Тестирование через мониторинг или холакратия на практике / Максим Чистяков (U...Тестирование через мониторинг или холакратия на практике / Максим Чистяков (U...
Тестирование через мониторинг или холакратия на практике / Максим Чистяков (U...
 
Производительность WebGL-приложений / Дмитренко Кирилл (Яндекс)
Производительность WebGL-приложений / Дмитренко Кирилл (Яндекс)Производительность WebGL-приложений / Дмитренко Кирилл (Яндекс)
Производительность WebGL-приложений / Дмитренко Кирилл (Яндекс)
 
Отладка производительности приложения на Erlang / Максим Лапшин (Erlyvideo)
 Отладка производительности приложения на Erlang / Максим Лапшин (Erlyvideo) Отладка производительности приложения на Erlang / Максим Лапшин (Erlyvideo)
Отладка производительности приложения на Erlang / Максим Лапшин (Erlyvideo)
 
Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)
Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)
Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)
 
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
 
Aviasales: миграция поискового движка в docker / Дмитрий Кузьменков (Aviasales)
Aviasales: миграция поискового движка в docker / Дмитрий Кузьменков (Aviasales)Aviasales: миграция поискового движка в docker / Дмитрий Кузьменков (Aviasales)
Aviasales: миграция поискового движка в docker / Дмитрий Кузьменков (Aviasales)
 
Юрий Насретдинов, Badoo
Юрий Насретдинов, BadooЮрий Насретдинов, Badoo
Юрий Насретдинов, Badoo
 
Анатомия веб-сервиса (РИТ-2014)
Анатомия веб-сервиса (РИТ-2014)Анатомия веб-сервиса (РИТ-2014)
Анатомия веб-сервиса (РИТ-2014)
 
Алексей Фомкин, Практическое применение Web Workers
Алексей Фомкин, Практическое применение Web WorkersАлексей Фомкин, Практическое применение Web Workers
Алексей Фомкин, Практическое применение Web Workers
 
"Fault tolerant workflow orchestration on PHP", Anton Tsitou
"Fault tolerant workflow orchestration on PHP", Anton Tsitou"Fault tolerant workflow orchestration on PHP", Anton Tsitou
"Fault tolerant workflow orchestration on PHP", Anton Tsitou
 
Практика разработки веб-серверов на Rust
Практика разработки веб-серверов на RustПрактика разработки веб-серверов на Rust
Практика разработки веб-серверов на Rust
 
Akka: как я перестал бояться и полюбил асинхронный код
Akka: как я перестал бояться и полюбил асинхронный кодAkka: как я перестал бояться и полюбил асинхронный код
Akka: как я перестал бояться и полюбил асинхронный код
 
«Write once run anywhere — почём опиум для народа?» Игорь Новиков, Scalr
«Write once run anywhere — почём опиум для народа?» Игорь Новиков, Scalr«Write once run anywhere — почём опиум для народа?» Игорь Новиков, Scalr
«Write once run anywhere — почём опиум для народа?» Игорь Новиков, Scalr
 
«Тотальный контроль производительности» Михаил Юматов, ЦИАН
«Тотальный контроль производительности» Михаил Юматов, ЦИАН«Тотальный контроль производительности» Михаил Юматов, ЦИАН
«Тотальный контроль производительности» Михаил Юматов, ЦИАН
 
Денис Иванов
Денис ИвановДенис Иванов
Денис Иванов
 
Путь к Go на конкретном примере
Путь к Go на конкретном примереПуть к Go на конкретном примере
Путь к Go на конкретном примере
 
Оптимизация производительности фронтенда / Игорь Алексеенко (HTML Academy)
Оптимизация производительности фронтенда / Игорь Алексеенко (HTML Academy)Оптимизация производительности фронтенда / Игорь Алексеенко (HTML Academy)
Оптимизация производительности фронтенда / Игорь Алексеенко (HTML Academy)
 

Semelhante a Async Python

Android - 11 - Multithreading
Android - 11 - MultithreadingAndroid - 11 - Multithreading
Android - 11 - MultithreadingNoveo
 
Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...
Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...
Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...SQALab
 
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...Yandex
 
Игры с виртуализацией в JavaScript, или как я переписал эмулятор, Евгений Пот...
Игры с виртуализацией в JavaScript, или как я переписал эмулятор, Евгений Пот...Игры с виртуализацией в JavaScript, или как я переписал эмулятор, Евгений Пот...
Игры с виртуализацией в JavaScript, или как я переписал эмулятор, Евгений Пот...Ontico
 
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)Ontico
 
"Девопс - это не только для программистов. Практические примеры из жизни одно...
"Девопс - это не только для программистов. Практические примеры из жизни одно..."Девопс - это не только для программистов. Практические примеры из жизни одно...
"Девопс - это не только для программистов. Практические примеры из жизни одно...it-people
 
Хорошо поддерживаемое в продакшне приложение / Николай Сивко (okmeter.io)
Хорошо поддерживаемое в продакшне приложение / Николай Сивко (okmeter.io)Хорошо поддерживаемое в продакшне приложение / Николай Сивко (okmeter.io)
Хорошо поддерживаемое в продакшне приложение / Николай Сивко (okmeter.io)Ontico
 
ВВЕДЕНИЕ В NODE.JS
ВВЕДЕНИЕ В NODE.JS ВВЕДЕНИЕ В NODE.JS
ВВЕДЕНИЕ В NODE.JS Pavel Tsukanov
 
Егор Гришечко «Async/Await и всё, что вы боялись спросить»
Егор Гришечко «Async/Await и всё, что вы боялись спросить»Егор Гришечко «Async/Await и всё, что вы боялись спросить»
Егор Гришечко «Async/Await и всё, что вы боялись спросить»SpbDotNet Community
 
CodeFest 2014. Каплуновский Б. — Использование асинхронного I/O для снижения ...
CodeFest 2014. Каплуновский Б. — Использование асинхронного I/O для снижения ...CodeFest 2014. Каплуновский Б. — Использование асинхронного I/O для снижения ...
CodeFest 2014. Каплуновский Б. — Использование асинхронного I/O для снижения ...CodeFest
 
CodeFest 2012. Липский Н. — JIT vs. AOT. Единство и борьба динамического и ст...
CodeFest 2012. Липский Н. — JIT vs. AOT. Единство и борьба динамического и ст...CodeFest 2012. Липский Н. — JIT vs. AOT. Единство и борьба динамического и ст...
CodeFest 2012. Липский Н. — JIT vs. AOT. Единство и борьба динамического и ст...CodeFest
 
Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...
Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...
Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...Badoo Development
 
Цикл разработки и внедрения функционала в Мамбе (Михаил Буйлов)
Цикл разработки и внедрения функционала в Мамбе (Михаил Буйлов)Цикл разработки и внедрения функционала в Мамбе (Михаил Буйлов)
Цикл разработки и внедрения функционала в Мамбе (Михаил Буйлов)Ontico
 
Асинхронные вызовы в .NET
Асинхронные вызовы в .NETАсинхронные вызовы в .NET
Асинхронные вызовы в .NETBonart
 
Анатомия веб-сервиса, Андрей Смирнов
Анатомия веб-сервиса, Андрей СмирновАнатомия веб-сервиса, Андрей Смирнов
Анатомия веб-сервиса, Андрей СмирновOntico
 
Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)
Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)
Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)Ontico
 
Анатомия веб-сервиса, Андрей Смирнов (ex-Skype)
Анатомия веб-сервиса, Андрей Смирнов (ex-Skype)Анатомия веб-сервиса, Андрей Смирнов (ex-Skype)
Анатомия веб-сервиса, Андрей Смирнов (ex-Skype)Ontico
 
Анатомия веб сервиса (HighLoad-2014)
Анатомия веб сервиса (HighLoad-2014)Анатомия веб сервиса (HighLoad-2014)
Анатомия веб сервиса (HighLoad-2014)Andrey Smirnov
 
разработка Metro style приложений
разработка Metro style приложенийразработка Metro style приложений
разработка Metro style приложенийОлег Винников
 

Semelhante a Async Python (20)

Android - 11 - Multithreading
Android - 11 - MultithreadingAndroid - 11 - Multithreading
Android - 11 - Multithreading
 
Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...
Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...
Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...
 
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
 
Игры с виртуализацией в JavaScript, или как я переписал эмулятор, Евгений Пот...
Игры с виртуализацией в JavaScript, или как я переписал эмулятор, Евгений Пот...Игры с виртуализацией в JavaScript, или как я переписал эмулятор, Евгений Пот...
Игры с виртуализацией в JavaScript, или как я переписал эмулятор, Евгений Пот...
 
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
 
"Девопс - это не только для программистов. Практические примеры из жизни одно...
"Девопс - это не только для программистов. Практические примеры из жизни одно..."Девопс - это не только для программистов. Практические примеры из жизни одно...
"Девопс - это не только для программистов. Практические примеры из жизни одно...
 
Хорошо поддерживаемое в продакшне приложение / Николай Сивко (okmeter.io)
Хорошо поддерживаемое в продакшне приложение / Николай Сивко (okmeter.io)Хорошо поддерживаемое в продакшне приложение / Николай Сивко (okmeter.io)
Хорошо поддерживаемое в продакшне приложение / Николай Сивко (okmeter.io)
 
ВВЕДЕНИЕ В NODE.JS
ВВЕДЕНИЕ В NODE.JS ВВЕДЕНИЕ В NODE.JS
ВВЕДЕНИЕ В NODE.JS
 
Егор Гришечко «Async/Await и всё, что вы боялись спросить»
Егор Гришечко «Async/Await и всё, что вы боялись спросить»Егор Гришечко «Async/Await и всё, что вы боялись спросить»
Егор Гришечко «Async/Await и всё, что вы боялись спросить»
 
Веб-сервер
Веб-серверВеб-сервер
Веб-сервер
 
CodeFest 2014. Каплуновский Б. — Использование асинхронного I/O для снижения ...
CodeFest 2014. Каплуновский Б. — Использование асинхронного I/O для снижения ...CodeFest 2014. Каплуновский Б. — Использование асинхронного I/O для снижения ...
CodeFest 2014. Каплуновский Б. — Использование асинхронного I/O для снижения ...
 
CodeFest 2012. Липский Н. — JIT vs. AOT. Единство и борьба динамического и ст...
CodeFest 2012. Липский Н. — JIT vs. AOT. Единство и борьба динамического и ст...CodeFest 2012. Липский Н. — JIT vs. AOT. Единство и борьба динамического и ст...
CodeFest 2012. Липский Н. — JIT vs. AOT. Единство и борьба динамического и ст...
 
Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...
Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...
Badoo в облаках. Решение для запуска cli-скриптов в облаке собственной разраб...
 
Цикл разработки и внедрения функционала в Мамбе (Михаил Буйлов)
Цикл разработки и внедрения функционала в Мамбе (Михаил Буйлов)Цикл разработки и внедрения функционала в Мамбе (Михаил Буйлов)
Цикл разработки и внедрения функционала в Мамбе (Михаил Буйлов)
 
Асинхронные вызовы в .NET
Асинхронные вызовы в .NETАсинхронные вызовы в .NET
Асинхронные вызовы в .NET
 
Анатомия веб-сервиса, Андрей Смирнов
Анатомия веб-сервиса, Андрей СмирновАнатомия веб-сервиса, Андрей Смирнов
Анатомия веб-сервиса, Андрей Смирнов
 
Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)
Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)
Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)
 
Анатомия веб-сервиса, Андрей Смирнов (ex-Skype)
Анатомия веб-сервиса, Андрей Смирнов (ex-Skype)Анатомия веб-сервиса, Андрей Смирнов (ex-Skype)
Анатомия веб-сервиса, Андрей Смирнов (ex-Skype)
 
Анатомия веб сервиса (HighLoad-2014)
Анатомия веб сервиса (HighLoad-2014)Анатомия веб сервиса (HighLoad-2014)
Анатомия веб сервиса (HighLoad-2014)
 
разработка Metro style приложений
разработка Metro style приложенийразработка Metro style приложений
разработка Metro style приложений
 

Async Python

  • 2. Проблема C10K • Условное название задачи конфигурирования и обслуживания высокопроизводительного сервера • Сервер должен быть способен обслуживать порядка 10 тыс. соединений одновременно
  • 3. Проблема C10K • Решение №1 • Поток на каждого клиента • Решение №2 • Поток на несколько клиентов
  • 4. Сервера, выдерживающие проблему • nginx, which relies on an event-driven (asynchronous) architecture, instead of threads, to handle requests • Lighttpd, which relies on an asynchronous architecture to handle requests • Tornado, a non-blocking web server and web application framework written in Python (used by Facebook's FriendFeed) • Apache AWF (retired, formerly Apache Deft), asynchronous, non-blocking web server running on the JVM • JBoss Netty, a NIO client server framework which enables quick and easy development of network applications such as protocol servers and clients • Node.js, asynchronous, non-blocking web server running on Google's V8 JavaScript engine
  • 5. Сервера, выдерживающие проблему • EventMachine, an asynchronous, non-blocking web server running on Ruby EventMachine • Cowboy (web server), another very lightweight web server written in Erlang • asyncore (in the standard Python library), a non- blocking web server library. It is based on Medusa, which is no longer maintained. • Django, some research is being done using the asynchronous IO support in Python 3.3
  • 7. Sync • Делится на однопоточную и многопоточную.
  • 8. Sync: 1 thread • В однопоточной модели каждая задача выполняется последовательно. Поток выполняет следующую задачу только тогда, когда предыдущая точно завершилась.
  • 9. Sync: N threads • В многопоточной модели можно достичь некоторой "одновременной работы" задач, но на каждую задачу выделяется один поток. Деталями управления в многопоточной синхронной модели управляет ОС.
  • 10. Async • Асинхронная модель всегда будет чередовать выполнение задач. Взаимодействие задач (их синхронизация) лежит на ответственности программиста.
  • 11. sync VS async • По сравнению с синхронной моделью, асинхронная модель лучше когда: 1. Когда есть много задач таких, что почти всегда есть по меньшей мере одна задача, которая может выполняться. 2. Задачи выполняют много операций ввода-вывода, приводя к тому, что синхронная задача проводит много времени впустую, блокируясь, в то время когда другие задачи могли бы выполняться. 3. Задачи независимы друг от друга и не нуждаются во взаимодействии.
  • 12. Event-driven programming • Событийно-ориентированное программирование • Способ построения программы • В коде явным образом выделяется главный цикл приложения • Тело главного цикла состоит из двух частей: выборки события и обработки события.
  • 13. Reactor • Для ожидания задач и управления ими, используется внешний цикл, который постоянно ждет каких-либо действий. • При возникновении задачи, он немедленно реагирует. • Каждая задача должна быть в не блокирующем режиме. какой смысл использовать реактор, если мы будем блокировать наш внешний цикл, который как раз и следит за приходом новых задач или выполнением следующих
  • 14. Async-servers in Python • Name Lic. Doc Ex. Prod. Com. Act. Blog Twt Rep. Pool Wsgi Scket Cmet Epoll Test Style • Twisted! MIT! Yes! Yes! Yes! Huge! Yes! Lots! No! Trac! Yes! Yes! Yes! No! Yes! Yes! Callback! • Tornado! Apache! Yes! Yes! F.Feed!Yes! Yes! FB! Yes! GHub! No! Lim.! Yes! No! Yes! No! Async! • Orbited MIT Yes Yes Yes Yes Yes Yes No Trac No No Yes Yes Yes Yes Callback • DieselWeb BSD Yes Yes STalk Yes Yes Yes Yes BitB. No Lim. Yes Yes Yes No Generator • MultiTask MIT Some No No No No Yes No Bzr No No No No No No Generator • Chiral GPL2 API No No IRC No No No Trac No Yes Yes Yes Yes Yes Coroutine • Eventlet! MIT! Yes! Yes! S. Life! Yes! Yes! Yes! No! BitB.! Yes! Yes! Yes! No! Yes! Yes! Greenlet! • FriendlyFlow GPL2 Some One No No No No Yes Ggle No No Yes No No Yes Generator • Weightless GPL2 Yes No Yes No No No Yes SF No No Yes No No Yes Generator • Fibra MIT No No No No No Yes No Ggle No No Yes No No No Generator • Concurrence! MIT! Yes! Yes! hyves!Yes! Yes! No! No! GHub! No! Yes! Yes! No! Yes! Yes! Tasklet! • Circuits MIT Yes Yes Yes Yes Yes Yes Yes Trac No Yes Yes No No Yes Async http://nichol.as/asynchronous-servers-in-python
  • 15. Async-servers in Python • What License does the framework have? • Does it provide documentation? • Does the documentation contain examples? • Is it used in production somewhere? • Does it have some sort of community (mailinglist, irc, etc..)? • Is there any recent activity? • Does it have a blog (from the owner)? • Does it have a twitter account? • Where can i find the repository? • Does it have a Thread Pool? • Does it provide access to a TCP Socket? • Does it have any Comet features? • Is it using EPOLL? • What kind of server is it? (greenlets, callbacks, generators etc..) http://nichol.as/asynchronous-servers-in-python
  • 16. Tornado • Расширяемый, неблокирующий веб-сервер и фреймворк, написанный на Python. • Создан для использования в проекте FriendFeed; компания была приобретена Facebook в 2009 году и после этого были открыты исходные коды Tornado.
  • 17. Tornado import tornado.httpserver import tornado.ioloop import tornado.options import tornado.web import logging from tornado.options import define, options ! define("port", default=8888, help="run on the given port", type=int) ! class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world!") ! def main(): tornado.options.parse_command_line() application = tornado.web.Application([ (r"/", MainHandler), ]) http_server = tornado.httpserver.HTTPServer(application) http_server.listen(options.port) tornado.ioloop.IOLoop.instance().start() ! if __name__ == "__main__": main() http://programmingzen.com/2009/09/13/benchmarking-tornado-vs-twisted-web-vs-tornado-on-twisted/
  • 18. Twisted • Проекты на Twisted могут поддерживать TCP, UDP, SSL/TLS, IP Multicast, Unix domain sockets, большое количество протоколов, включая HTTP, XMPP, NNTP, IMAP, SSH, IRC, FTP и другие. • Основан на парадигме событийно- ориентированного программирования, и это значит, что пользователи Twisted пишут небольшие программы обратного вызова, которые вызываются фреймворком.
  • 19. Twisted from twisted.internet import epollreactor epollreactor.install() from twisted.internet import reactor from twisted.web import server, resource ! ! class Simple(resource.Resource): isLeaf = True def render_GET(self, request): return "Hello, world!" ! ! site = server.Site(Simple()) reactor.listenTCP(8888, site) reactor.run() http://programmingzen.com/2009/09/13/benchmarking-tornado-vs-twisted-web-vs-tornado-on-twisted/
  • 21. Twisted • Шаблон реактор - однопоточный. • Twisted сам реализует цикл реактора, мы сами не должны его реализовывать. • При написании кода, нужно продумывать основную логику задачи. • Цикл реактора вызывает наш код в тот момент, когда мы об этом сами скажем. Реактор наперед не может знать, какую часть кода нужно вызвать. • Когда наши callback’и выполняются, цикл реактора не выполняется, и наоборот. • После возврата из callback'а, цикл реактора возобновляется
  • 23. Errbacks • Реактор не обрабатывает исключения, потому что ничего о них не знает. • Реактор -- низкоуровневый метод, а исключения генерируются из более высокоуровневого кода.
  • 24. Sync VS Async 1. Синхронный код:! try:! text = run_print()! except Exception, err:! print err! sys.exit()! else:! print text! sys.exit()! ! ! 2. Асинхронный код:! def print_ok(text):! print text! reactor.stop()! ! def print_fail(err):! print >>sys.stderr, err! reactor.stop()! ! run_print(print_ok, print_err)! ! reactor.run()
  • 25. Deferred from twisted.internet.defer import Deferred! ! def print_ok(text):! print text! ! def print_fail(err):! print >>sys.stderr, err! ! d = Deferred()! d.addCallbacks(print_ok, print_fail)! d.callback("Text is correct") ! # или d.errback(Exception('I have failed.'))! print "End."! ! reactor.run()
  • 27. Сервер на Twisted from twisted.internet import reactor! from twisted.internet.protocol import ServerFactory ! from twisted.protocols.basic import LineOnlyReceiver ! ! class ChatProtocol(LineOnlyReceiver): ! ! name = "" ! def getName(self): ! if self.name!="": ! return self.name ! return self.transport.getPeer().host ! ! def connectionMade(self): ! print "New connection from "+self.getName() ! self.sendLine("Welcome to my my chat server.") ! self.sendLine("Send '/NAME [new name]' to change your name.") ! self.sendLine("Send '/EXIT' to quit.") ! self.factory.sendMessageToAllClients(self.getName()+" has joined the party.") ! self.factory.clientProtocols.append(self)
  • 28. Сервер на Twisted ! ! def connectionLost(self, reason): ! print "Lost connection from "+self.getName() ! self.factory.clientProtocols.remove(self) ! self.factory.sendMessageToAllClients(self.getName()+" has disconnected.") ! ! def lineReceived(self, line): ! print self.getName()+" said "+line ! if line[:5]=="/NAME": ! oldName = self.getName() ! self.name = line[5:].strip() ! self.factory.sendMessageToAllClients(oldName+" changed name ! ! ! ! ! to "+self.getName()) ! elif line=="/EXIT": ! self.transport.loseConnection() ! else: ! self.factory.sendMessageToAllClients(self.getName()+" says "+line) ! ! def sendLine(self, line): ! self.transport.write(line+"rn") ! !
  • 29. Сервер на Twisted class ChatProtocolFactory(ServerFactory): ! ! protocol = ChatProtocol ! ! def __init__(self): ! self.clientProtocols = [] ! ! def sendMessageToAllClients(self, mesg): ! for client in self.clientProtocols:! client.sendLine(mesg) ! ! print "Starting Server"! factory = ChatProtocolFactory()! reactor.listenTCP(12345, factory)! reactor.run()! В качестве клиента: telnet localhost 12345
  • 30. Async I/O for Python 3 • Пишем асинхронный код без тредов и коллбеков • Сопрограмма (англ. coroutine) — компонент программы, обобщающий понятие подпрограммы, который дополнительно поддерживает множество входных точек (а не одну как подпрограмма) и остановку и продолжение выполнения с сохранением определённого положения.
  • 31. Yield from ! ! class BinaryTree_ForLoop:! def __init__(self, left=None, us=None, right=None):! self.left = left! self.us = us! self.right = right! ! def __iter__(self):! if self.left:! for node in self.left:! yield node! if self.us:! yield self.us! if self.right:! for node in self.right:! yield node! class BinaryTree:! def __init__(self, ! left=None, us=None, right=None):! self.left = left! self.us = us! self.right = right! ! def __iter__(self):! if self.left:! yield from self.left! if self.us:! yield self.us! if self.right:! yield from self.right! ! # For comparison, here is the same thing using for-loops! # instead of yield-from.
  • 32. Tulip VS Twisted import tulip! from tulip import http! ! @tulip.coroutine! def download(url):! response = yield from http.request('GET', url)! for k, v in response.items():! print('{}: {}'.format(k, v[:80]))! ! data = yield from response.read()! print('nReceived {} bytes.n'.format(len(data)))! ! if __name__ == '__main__':! loop = tulip.get_event_loop()! coroutine = download('http://omegafeihong.tumblr.com')! loop.run_until_complete(coroutine)
  • 33. Tulip VS Twisted from twisted.internet import reactor! from twisted.internet.defer import Deferred, succeed! from twisted.internet.protocol import Protocol! from twisted.web.client import Agent! ! def print_headers(response):! for k, v in response.headers.getAllRawHeaders():! print('{}: {}'.format(k, v[0][:80]))! ! return get_response_body(response)! ! def get_response_body(response):! class BodyReceiver(Protocol):! def dataReceived(self, data):! chunks.append(data)! def connectionLost(self, reason):! finished.callback(''.join(chunks))! ! finished = Deferred()! chunks = []! response.deliverBody(BodyReceiver())! return finished! ! def print_body(data):! print('nReceived {} bytes.n'.format(len(data)))! return succeed(None)! ! if __name__ == '__main__':! agent = Agent(reactor)! d = agent.request('GET', 'http://megafei d.addCallback(print_headers)! d.addCallback(print_body)! d.addCallback(lambda x: reactor.stop())! reactor.run()
  • 34. Почитать • http://ninaevseenko.github.io/async_twisted_ru/async_twisted_ru.pdf • http://legacy.python.org/dev/peps/pep-3156/#abstract • http://moscowdjango.ru/meetup/18/tulip/ • http://neednourishment.blogspot.ru • http://www.ibm.com/developerworks/ru/library/l-python_part_10/index.html • http://www.slideshare.net/Smirnov.Andrey/twisted-framework-python-2211313 • http://moscowdjango.ru/meetup/14/gil-and-python-why/ • http://legacy.python.org/dev/peps/pep-0380/ • http://legacy.python.org/dev/peps/pep-3156/#event-loop-classes • http://ru.wikipedia.org/wiki/%D1%EE%E1%FB%F2%E8%E9%ED%EE-%EE%F0%E8%E5%ED%F2%E8%F0%EE%E2%E0%ED %ED%EE%E5_%EF%F0%EE%E3%F0%E0%EC%EC%E8%F0%EE%E2%E0%ED%E8%E5 • http://nichol.as/asynchronous-servers-in-python • http://programmingzen.com/2009/09/13/benchmarking-tornado-vs-twisted-web-vs-tornado-on-twisted/ • http://www.slideshare.net/megafeihong/tulip-24190096 • http://www.dabeaz.com/coroutines/