SlideShare uma empresa Scribd logo
1 de 154
Distributed Systems
 with ZeroMQ and gevent

                 Jeff Lindsay
                 @progrium
Why distributed systems?

 Harness more CPUs and resources
 Run faster in parallel
 Tolerance of individual failures
 Better separation of concerns
Most web apps evolve into
  distributed systems
OpenStack
Amazon AWS

                        Provider

Web




                           Provider
 API




Client

                         Provider

   TwiML
ZeroMQ + gevent
Two powerful and misunderstood tools
Concurrency
Heart of Distributed Systems
Distributed computing
is just another flavor of
    local concurrency
Multithreading
         Shared Memory


Thread       Thread        Thread



  Distributed system
         Shared Database


 App          App           App
Concurrency models


Execution model
 Defines the “computational unit”

Communication model
 Means of sharing and coordination
Concurrency models
Traditional multithreading
  OS threads
  Shared memory, locks, etc
Async or Evented I/O
  I/O loop + callback chains
  Shared memory, futures
Actor model
  Shared nothing “processes”
  Built-in messaging
Examples
Erlang
  Actor model
Scala
  Actor model
Go
  Channels, Goroutines
Everything else (Ruby, Python, PHP, Perl, C/C++, Java)
  Threading
  Evented
Erlang is special.


     Normally, the networking of
distributed systems is tacked on to the
       local concurrency model.

            MQ, RPC, REST, ...
Why not always use Erlang?
Why not always use Erlang?
Half reasons
 Weird/ugly language
 Limited library ecosystem
 VM requires operational expertise
 Functional programming isn’t mainstream
Why not always use Erlang?
Half reasons
  Weird/ugly language
  Limited library ecosystem
  VM requires operational expertise
  Functional programming isn’t mainstream
Biggest reason
  It’s not always the right tool for the job
Amazon AWS

                        Provider

Web




                           Provider
 API




Client

                         Provider

   TwiML
Service Oriented
  Architecture
    Multiple languages
   Heterogeneous cluster
RPC
RPC
Client / server
RPC
Client / server
Mapping to functions
RPC
Client / server
Mapping to functions
Message serialization
RPC
       Client / server
       Mapping to functions
       Message serialization

Poor abstraction of what you really want
What you want are tools to help you get distributed
actor model concurrency like Erlang ... without Erlang.
     Even better if they're decoupled and optional.
Rarely will you build an application as
part of a distributed system that does
   not also need local concurrency.
Communication model

How do we unify communications in local concurrency
     and distributed systems across languages?
Execution model

How do we get Erlang-style local concurrency without
 interfering with the language's idiomatic paradigm?
ZeroMQ
Communication model
Misconceptions
Misconceptions

It’s just another MQ, right?
Misconceptions

It’s just another MQ, right?
   Not really.
Misconceptions

It’s just another MQ, right?
   Not really.
Misconceptions

It’s just another MQ, right?
   Not really.

Oh, it’s just sockets, right?
Misconceptions

It’s just another MQ, right?
   Not really.

Oh, it’s just sockets, right?
 Not really.
Misconceptions

It’s just another MQ, right?
   Not really.

Oh, it’s just sockets, right?
 Not really.
Misconceptions

It’s just another MQ, right?
   Not really.

Oh, it’s just sockets, right?
 Not really.

Wait, isn’t messaging a solved problem?
Misconceptions

It’s just another MQ, right?
   Not really.

Oh, it’s just sockets, right?
 Not really.

Wait, isn’t messaging a solved problem?
 *sigh* ... maybe.
Regular Sockets
Regular Sockets


Point to point
Regular Sockets


Point to point
Stream of bytes
Regular Sockets


Point to point
Stream of bytes
Buffering
Regular Sockets


Point to point
Stream of bytes
Buffering
Standard API
Regular Sockets


Point to point
Stream of bytes
Buffering
Standard API
TCP/IP or UDP, IPC
Messaging
Messaging
Messages are atomic
Messaging
Messages are atomic
Messaging
Messages are atomic
Messaging
Messages are atomic
Messaging
Messages are atomic   Messages can be routed
Messaging
Messages are atomic   Messages can be routed
Messaging
Messages are atomic   Messages can be routed
Messaging
 Messages are atomic      Messages can be routed




Messages may sit around
Messaging
 Messages are atomic      Messages can be routed




Messages may sit around
Messaging
 Messages are atomic      Messages can be routed




Messages may sit around
Messaging
 Messages are atomic      Messages can be routed




Messages may sit around
Messaging
 Messages are atomic      Messages can be routed




Messages may sit around
Messaging
 Messages are atomic      Messages can be routed




Messages may sit around
Messaging
 Messages are atomic      Messages can be routed




Messages may sit around   Messages are delivered
Messaging
 Messages are atomic      Messages can be routed




Messages may sit around   Messages are delivered
Rise of the Big MQ
App
      App




               Reliable
            Message Broker


               Persistent
                 Queues
                                   App
App
App
      App




                  App
App
AMQP

            MQ




Producer
                  Consumer
AMQP

                           MQ



                      Binding
Producer      X
                                        Consumer
           Exchange             Queue
AMQP

                       MQ




Producer      X
                                    Consumer
           Exchange         Queue
AMQP Recipes
AMQP Recipes
Work queues
Distributing tasks among workers
AMQP Recipes
Work queues                        Publish/Subscribe
Distributing tasks among workers   Sending to many consumers at once



                                           X
AMQP Recipes
Work queues                        Publish/Subscribe
Distributing tasks among workers   Sending to many consumers at once



                                           X




Routing
Receiving messages selectively

             foo

        X     bar

            baz
AMQP Recipes
Work queues                        Publish/Subscribe
Distributing tasks among workers   Sending to many consumers at once



                                           X




Routing                            RPC
Receiving messages selectively     Remote procedure call implementation

             foo

        X     bar

            baz
Drawbacks of Big MQ

   Lots of complexity
   Queues are heavyweight
   HA is a challenge
   Poor primitives
Enter ZeroMQ
“Float like a butterfly, sting like a bee”
Echo in Python
                Server                                     Client

1   import zmq                             1   import zmq
2   context = zmq.Context()                2   context = zmq.Context()
3   socket = context.socket(zmq.REP)       3   socket = context.socket(zmq.REQ)
4   socket.bind("tcp://127.0.0.1:5000")    4   socket.connect("tcp://127.0.0.1:5000")
5                                          5
6   while True:                            6   for i in range(10):
7       msg = socket.recv()                7       msg = "msg %s" % i
8       print "Received", msg              8       socket.send(msg)
9       socket.send(msg)                   9       print "Sending", msg
                                          10       reply = socket.recv()
Echo in Ruby
                 Server                                     Client

 1   require "zmq"                          1   require "zmq"
 2   context = ZMQ::Context.new(1)          2   context = ZMQ::Context.new(1)
 3   socket = context.socket(ZMQ::REP)      3   socket = context.socket(ZMQ::REQ)
 4   socket.bind("tcp://127.0.0.1:5000")    4   socket.connect("tcp://127.0.0.1:5000")
 5                                          5
 6   loop do                                6   (0...10).each do |i|
 7       msg = socket.recv                  7       msg = "msg #{i}"
 8       puts "Received #{msg}"             8       socket.send(msg)
 9       socket.send(msg)                   9       puts "Sending #{msg}"
10   end                                   10       reply = socket.recv
                                           11   end
Echo in PHP
                     Server                                               Client

 1   <?php                                              1   <?php
 2   $context = new ZMQContext();                       2   $context = new ZMQContext();
 3   $socket = $context->getSocket(ZMQ::SOCKET_REP);    3   $socket = $context->getSocket(ZMQ::SOCKET_REQ);
 4   $socket->bind("tcp://127.0.0.1:5000");             4   $socket->connect("tcp://127.0.0.1:5000");
 5                                                      5
 6   while (true) {                                     6   foreach (range(0, 9) as $i) {
 7       $msg = $socket->recv();                        7       $msg = "msg {$i}";
 8       echo "Received {$msg}";                        8       $socket->send($msg);
 9       $socket->send($msg);                           9       echo "Sending {$msg}";
10   }                                                 10       $reply = $socket->recv();
11   ?>                                                11   }
                                                       12   ?>
Bindings

 ActionScript, Ada, Bash, Basic, C, Chicken
 Scheme, Common Lisp, C#, C++, D, Erlang,
F#, Go, Guile, Haskell, Haxe, Java, JavaScript,
 Lua, Node.js, Objective-C, Objective Caml,
  ooc, Perl, PHP, Python, Racket, REBOL,
             Red, Ruby, Smalltalk
Plumbing
Plumbing
Plumbing
Plumbing
Plumbing
Plumbing

inproc
ipc
tcp
multicast
Plumbing

inproc
ipc
tcp
multicast

  socket.bind("tcp://localhost:5560")
  socket.bind("ipc:///tmp/this-socket")
  socket.connect("tcp://10.0.0.100:9000")
  socket.connect("ipc:///tmp/another-socket")
  socket.connect("inproc://another-socket")
Plumbing

inproc
ipc
tcp
multicast

  socket.bind("tcp://localhost:5560")
  socket.bind("ipc:///tmp/this-socket")
  socket.connect("tcp://10.0.0.100:9000")
  socket.connect("ipc:///tmp/another-socket")
  socket.connect("inproc://another-socket")
Plumbing

inproc
ipc
tcp
multicast

  socket.bind("tcp://localhost:5560")
  socket.bind("ipc:///tmp/this-socket")
  socket.connect("tcp://10.0.0.100:9000")
  socket.connect("ipc:///tmp/another-socket")
  socket.connect("inproc://another-socket")
Message Patterns
Message Patterns
Request-Reply


REQ      REP
Message Patterns
Request-Reply
       REP


REQ          REP


       REP
Message Patterns
Request-Reply
       REP


REQ          REP


       REP
Message Patterns
Request-Reply
       REP


REQ          REP


       REP
Message Patterns
Request-Reply
       REP


REQ          REP


       REP
Message Patterns
Request-Reply      Publish-Subscribe
       REP                  SUB


REQ          REP     PUB          SUB


       REP                  SUB
Message Patterns
   Request-Reply           Publish-Subscribe
            REP                     SUB


    REQ           REP        PUB          SUB


            REP                     SUB




Push-Pull (Pipelining)
             PULL


     PUSH           PULL


            PULL
Message Patterns
   Request-Reply           Publish-Subscribe
            REP                     SUB


    REQ           REP        PUB          SUB


            REP                     SUB




Push-Pull (Pipelining)
             PULL


     PUSH           PULL


            PULL
Message Patterns
   Request-Reply           Publish-Subscribe
            REP                     SUB


    REQ           REP        PUB          SUB


            REP                     SUB




Push-Pull (Pipelining)
             PULL


     PUSH           PULL


            PULL
Message Patterns
   Request-Reply           Publish-Subscribe
            REP                     SUB


    REQ           REP        PUB          SUB


            REP                     SUB




Push-Pull (Pipelining)
             PULL


     PUSH           PULL


            PULL
Message Patterns
   Request-Reply           Publish-Subscribe
            REP                        SUB


    REQ           REP        PUB             SUB


            REP                        SUB




Push-Pull (Pipelining)              Pair
             PULL


                    PULL     PAIR             PAIR
     PUSH


            PULL
Devices
Queue         Forwarder            Streamer




   Design architectures around devices.
Devices
Queue          Forwarder           Streamer


         REQ                 REP




   Design architectures around devices.
Devices
Queue          Forwarder           Streamer


         PUB                 SUB




   Design architectures around devices.
Devices
Queue           Forwarder           Streamer


         PUSH                PULL




   Design architectures around devices.
Performance
Performance


Orders of magnitude faster than most MQs
Performance


Orders of magnitude faster than most MQs
Higher throughput than raw sockets
Performance


Orders of magnitude faster than most MQs
Higher throughput than raw sockets
 Intelligent message batching
Performance


Orders of magnitude faster than most MQs
Higher throughput than raw sockets
 Intelligent message batching
 Edge case optimizations
Concurrency?
"Come for the messaging, stay for the easy concurrency"
Hintjens’ Law of Concurrency

            e=      mc 2

    E is effort, the pain that it takes
    M is mass, the size of the code
    C is conflict, when C threads collide
Hintjens’ Law of Concurrency
Hintjens’ Law of Concurrency
Hintjens’ Law of Concurrency


         ZeroMQ:
   e=mc 2,   for c=1
ZeroMQ

    Easy       ... familiar socket API
    Cheap      ... lightweight queues in a library
    Fast       ... higher throughput than raw TCP
    Expressive ... maps to your architecture

Messaging toolkit for concurrency and distributed systems.
gevent
Execution model
Threading vs Evented
Evented seems to be preferred for scalable I/O applications
Evented Stack
  Non-blocking Code


    Flow Control


   I/O Abstraction


      Reactor
                       I/O
                      Loop
     Event Poller
1   def lookup(country, search_term):
 2       main_d = defer.Deferred()
 3
 4       def first_step():
 5           query = "http://www.google.%s/search?q=%s" % (country,search_term)
 6           d = getPage(query)
 7           d.addCallback(second_step, country)
 8           d.addErrback(failure, country)
 9
10       def second_step(content, country):
11           m = re.search('<div id="?res.*?href="(?P<url>http://[^"]+)"',
12                         content, re.DOTALL)
13           if not m:
14               main_d.callback(None)
15               return
16           url = m.group('url')
17           d = getPage(url)
18           d.addCallback(third_step, country, url)
19           d.addErrback(failure, country)
20
21       def third_step(content, country, url):
22           m = re.search("<title>(.*?)</title>", content)
23           if m:
24               title = m.group(1)
25               main_d.callback(dict(url = url, title = title))
26           else:
27               main_d.callback(dict(url=url, title="{not-specified}"))
28
29       def failure(e, country):
30           print ".%s FAILED: %s" % (country, str(e))
31           main_d.callback(None)
32
33       first_step()
34       return main_d
gevent


     “Regular” Python


Greenlets       Monkey patching


   Reactor / Event Poller
Green threads
“Threads” implemented in user space (VM, library)
Monkey patching
  socket, ssl, threading, time
Twisted
Twisted
~400 modules
gevent
25 modules
Performance




              http://nichol.as
Performance




              http://nichol.as
Performance




              http://nichol.as
Building a Networking App
 1   #===
 2   # 1. Basic gevent TCP server
 3
 4   from gevent.server import StreamServer
 5
 6   def handle_tcp(socket, address):
 7       print 'new tcp connection!'
 8       while True:
 9           socket.send('hellon')
10           gevent.sleep(1)
11
12   tcp_server = StreamServer(('127.0.0.1', 1234), handle_tcp)
13   tcp_server.serve_forever()
1   #===
 2   # 2. Basic gevent TCP server and WSGI server
 3
 4   from gevent.pywsgi import WSGIServer
 5   from gevent.server import StreamServer
 6
 7   def handle_http(env, start_response):
 8       start_response('200 OK', [('Content-Type', 'text/html')])
 9       print 'new http request!'
10       return ["hello world"]
11
12   def handle_tcp(socket, address):
13       print 'new tcp connection!'
14       while True:
15           socket.send('hellon')
16           gevent.sleep(1)
17
18   tcp_server = StreamServer(('127.0.0.1', 1234), handle_tcp)
19   tcp_server.start()
20
21   http_server = WSGIServer(('127.0.0.1', 8080), handle_http)
22   http_server.serve_forever()
1   from gevent.pywsgi import WSGIServer
 2   from gevent.server import StreamServer
 3   from gevent.socket import create_connection
 4
 5   def handle_http(env, start_response):
 6       start_response('200 OK', [('Content-Type', 'text/html')])
 7       print 'new http request!'
 8       return ["hello world"]
 9
10   def handle_tcp(socket, address):
11       print 'new tcp connection!'
12       while True:
13           socket.send('hellon')
14           gevent.sleep(1)
15
16   def client_connect(address):
17       sockfile = create_connection(address).makefile()
18       while True:
19           line = sockfile.readline() # returns None on EOF
20           if line is not None:
21               print "<<<", line,
22           else:
23               break
24
25   tcp_server = StreamServer(('127.0.0.1', 1234), handle_tcp)
26   tcp_server.start()
27
28   gevent.spawn(client_connect, ('127.0.0.1', 1234))
29
30   http_server = WSGIServer(('127.0.0.1', 8080), handle_http)
31   http_server.serve_forever()
1   from gevent.pywsgi import WSGIServer
 2   from gevent.server import StreamServer
 3   from gevent.socket import create_connection
 4
 5   def handle_http(env, start_response):
 6       start_response('200 OK', [('Content-Type', 'text/html')])
 7       print 'new http request!'
 8       return ["hello world"]
 9
10   def handle_tcp(socket, address):
11       print 'new tcp connection!'
12       while True:
13           socket.send('hellon')
14           gevent.sleep(1)
15
16   def client_connect(address):
17       sockfile = create_connection(address).makefile()
18       while True:
19           line = sockfile.readline() # returns None on EOF
20           if line is not None:
21               print "<<<", line,
22           else:
23               break
24
25   tcp_server = StreamServer(('127.0.0.1', 1234), handle_tcp)
26   http_server = WSGIServer(('127.0.0.1', 8080), handle_http)
27   greenlets = [
28       gevent.spawn(tcp_server.serve_forever),
29       gevent.spawn(http_server.serve_forever),
30       gevent.spawn(client_connect, ('127.0.0.1', 1234)),
31   ]
32   gevent.joinall(greenlets)
ZeroMQ in gevent?
1   from gevent import spawn
 2   from gevent_zeromq import zmq
 3
 4   context = zmq.Context()
 5
 6   def serve():
 7       socket = context.socket(zmq.REP)
 8       socket.bind("tcp://localhost:5559")
 9       while True:
10           message = socket.recv()
11           print "Received request: ", message
12           socket.send("World")
13
14   server = spawn(serve)
15
16   def client():
17       socket = context.socket(zmq.REQ)
18       socket.connect("tcp://localhost:5559")
19       for request in range(10):
20           socket.send("Hello")
21           message = socket.recv()
22           print "Received reply ", request, "[", message, "]"
23
24   spawn(client).join()
Actor model?
Easy to implement, in whole or in part,
       optionally with ZeroMQ
What is gevent missing?
What is gevent missing?


    Documentation
What is gevent missing?


    Documentation
    Application framework
gservice
Application framework for gevent
1   from gevent.pywsgi import WSGIServer
 2   from gevent.server import StreamServer
 3   from gevent.socket import create_connection
 4
 5   def handle_http(env, start_response):
 6       start_response('200 OK', [('Content-Type', 'text/html')])
 7       print 'new http request!'
 8       return ["hello world"]
 9
10   def handle_tcp(socket, address):
11       print 'new tcp connection!'
12       while True:
13           socket.send('hellon')
14           gevent.sleep(1)
15
16   def client_connect(address):
17       sockfile = create_connection(address).makefile()
18       while True:
19           line = sockfile.readline() # returns None on EOF
20           if line is not None:
21               print "<<<", line,
22           else:
23               break
24
25   tcp_server = StreamServer(('127.0.0.1', 1234), handle_tcp)
26   http_server = WSGIServer(('127.0.0.1', 8080), handle_http)
27   greenlets = [
28       gevent.spawn(tcp_server.serve_forever),
29       gevent.spawn(http_server.serve_forever),
30       gevent.spawn(client_connect, ('127.0.0.1', 1234)),
31   ]
32   gevent.joinall(greenlets)
1   from gevent.pywsgi import WSGIServer
 2   from gevent.server import StreamServer
 3   from gevent.socket import create_connection
 4
 5   from gservice.core import Service
 6
 7   def handle_http(env, start_response):
 8       start_response('200 OK', [('Content-Type', 'text/html')])
 9       print 'new http request!'
10       return ["hello world"]
11
12   def handle_tcp(socket, address):
13       print 'new tcp connection!'
14       while True:
15           socket.send('hellon')
16           gevent.sleep(1)
17
18   def client_connect(address):
19       sockfile = create_connection(address).makefile()
20       while True:
21           line = sockfile.readline() # returns None on EOF
22           if line is not None:
23               print "<<<", line,
24           else:
25               break
26
27   app = Service()
28   app.add_service(StreamServer(('127.0.0.1', 1234), handle_tcp))
29   app.add_service(WSGIServer(('127.0.0.1', 8080), handle_http))
30   app.add_service(TcpClient(('127.0.0.1', 1234), client_connect))
31   app.serve_forever()
1   from gservice.core import Service
 2   from gservice.config import Setting
 3
 4   class MyApplication(Service):
 5       http_port = Setting('http_port')
 6       tcp_port = Setting('tcp_port')
 7       connect_address = Setting('connect_address')
 8
 9       def __init__(self):
10           self.add_service(WSGIServer(('127.0.0.1', self.http_port), self.handle_http))
11           self.add_service(StreamServer(('127.0.0.1', self.tcp_port), self.handle_tcp))
12           self.add_service(TcpClient(self.connect_address, self.client_connect))
13
14       def client_connect(self, address):
15           sockfile = create_connection(address).makefile()
16           while True:
17               line = sockfile.readline() # returns None on EOF
18               if line is not None:
19                   print "<<<", line,
20               else:
21                   break
22
23       def handle_tcp(self, socket, address):
24           print 'new tcp connection!'
25           while True:
26               socket.send('hellon')
27               gevent.sleep(1)
28
29       def handle_http(self, env, start_response):
30           start_response('200 OK', [('Content-Type', 'text/html')])
31           print 'new http request!'
32           return ["hello world"]
1   # example.conf.py
 2
 3   pidfile = 'example.pid'
 4   logfile = 'example.log'
 5   http_port = 8080
 6   tcp_port = 1234
 7   connect_address = ('127.0.0.1', 1234)
 8
 9   def service():
10       from example import MyApplication
11       return MyApplication()


     # Run in the foreground
     gservice -C example.conf.py

     # Start service as daemon
     gservice -C example.conf.py start

     # Control service
     gservice -C example.conf.py restart
     gservice -C example.conf.py reload
     gservice -C example.conf.py stop

     # Run with overriding configuration
     gservice -C example.conf.py -X 'http_port = 7070'
Generalizing
gevent proves a model that can be implemented in almost
   any language that can implement an evented stack
gevent

 Easy       ... just normal Python
 Small      ... only 25 modules
 Fast       ... top performing server
 Compatible ... works with most libraries

Futuristic evented platform for network applications.
Raiden
 Lightning fast, scalable messaging

https://github.com/progrium/raiden
Concurrency models


Traditional multithreading

Async or Evented I/O

Actor model
Conclusion


Two very simple, but very powerful tools
  for distributed / concurrent systems
Thanks
 @progrium

Mais conteúdo relacionado

Mais procurados

Distributed app development with nodejs and zeromq
Distributed app development with nodejs and zeromqDistributed app development with nodejs and zeromq
Distributed app development with nodejs and zeromq
Ruben Tan
 

Mais procurados (20)

NullMQ @ PDX
NullMQ @ PDXNullMQ @ PDX
NullMQ @ PDX
 
Introduction to ZeroMQ - eSpace TechTalk
Introduction to ZeroMQ - eSpace TechTalkIntroduction to ZeroMQ - eSpace TechTalk
Introduction to ZeroMQ - eSpace TechTalk
 
ZeroMQ with NodeJS
ZeroMQ with NodeJSZeroMQ with NodeJS
ZeroMQ with NodeJS
 
ZeroMQ
ZeroMQZeroMQ
ZeroMQ
 
FOSDEM 2011 - 0MQ
FOSDEM 2011 - 0MQFOSDEM 2011 - 0MQ
FOSDEM 2011 - 0MQ
 
Distributed app development with nodejs and zeromq
Distributed app development with nodejs and zeromqDistributed app development with nodejs and zeromq
Distributed app development with nodejs and zeromq
 
RestMS Introduction
RestMS IntroductionRestMS Introduction
RestMS Introduction
 
Zeromq anatomy & jeromq
Zeromq anatomy & jeromqZeromq anatomy & jeromq
Zeromq anatomy & jeromq
 
Leveraging zeromq for node.js
Leveraging zeromq for node.jsLeveraging zeromq for node.js
Leveraging zeromq for node.js
 
Python Ireland 2012 - Message brokers and Python by Fernando Ciciliati
Python Ireland 2012 - Message brokers and Python by Fernando Ciciliati Python Ireland 2012 - Message brokers and Python by Fernando Ciciliati
Python Ireland 2012 - Message brokers and Python by Fernando Ciciliati
 
gen_udp and gen_tcp in Elixir
gen_udp and gen_tcp in Elixirgen_udp and gen_tcp in Elixir
gen_udp and gen_tcp in Elixir
 
Zero mq logs
Zero mq logsZero mq logs
Zero mq logs
 
sshuttle VPN (2011-04)
sshuttle VPN (2011-04)sshuttle VPN (2011-04)
sshuttle VPN (2011-04)
 
play framework async with scala
play framework async with scalaplay framework async with scala
play framework async with scala
 
AHA-best-msf-interface-ever
AHA-best-msf-interface-everAHA-best-msf-interface-ever
AHA-best-msf-interface-ever
 
memcached Binary Protocol in a Nutshell
memcached Binary Protocol in a Nutshellmemcached Binary Protocol in a Nutshell
memcached Binary Protocol in a Nutshell
 
Netty @Apple: Large Scale Deployment/Connectivity
Netty @Apple: Large Scale Deployment/ConnectivityNetty @Apple: Large Scale Deployment/Connectivity
Netty @Apple: Large Scale Deployment/Connectivity
 
Let your stuff talk!
Let your stuff talk!Let your stuff talk!
Let your stuff talk!
 
Gabriele Santomaggio - Inside Elixir/Erlang - Codemotion Milan 2018
Gabriele Santomaggio - Inside Elixir/Erlang - Codemotion Milan 2018Gabriele Santomaggio - Inside Elixir/Erlang - Codemotion Milan 2018
Gabriele Santomaggio - Inside Elixir/Erlang - Codemotion Milan 2018
 
PHP at Density and Scale
PHP at Density and ScalePHP at Density and Scale
PHP at Density and Scale
 

Semelhante a Lindsay distributed geventzmq

Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...
Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...
Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...
Ontico
 
The Future of Messaging: RabbitMQ and AMQP
The Future of Messaging: RabbitMQ and AMQP The Future of Messaging: RabbitMQ and AMQP
The Future of Messaging: RabbitMQ and AMQP
Eberhard Wolff
 
Of the variedtypes of IPC, sockets arout and awaythe foremostcommon..pdf
Of the variedtypes of IPC, sockets arout and awaythe foremostcommon..pdfOf the variedtypes of IPC, sockets arout and awaythe foremostcommon..pdf
Of the variedtypes of IPC, sockets arout and awaythe foremostcommon..pdf
anuradhasilks
 
NoSQL afternoon in Japan Kumofs & MessagePack
NoSQL afternoon in Japan Kumofs & MessagePackNoSQL afternoon in Japan Kumofs & MessagePack
NoSQL afternoon in Japan Kumofs & MessagePack
Sadayuki Furuhashi
 
NoSQL afternoon in Japan kumofs & MessagePack
NoSQL afternoon in Japan kumofs & MessagePackNoSQL afternoon in Japan kumofs & MessagePack
NoSQL afternoon in Japan kumofs & MessagePack
Sadayuki Furuhashi
 

Semelhante a Lindsay distributed geventzmq (20)

Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...
Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...
Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...
 
Scaling application with RabbitMQ
Scaling application with RabbitMQScaling application with RabbitMQ
Scaling application with RabbitMQ
 
Microservices Practitioner Summit Jan '15 - Don't Build a Distributed Monolit...
Microservices Practitioner Summit Jan '15 - Don't Build a Distributed Monolit...Microservices Practitioner Summit Jan '15 - Don't Build a Distributed Monolit...
Microservices Practitioner Summit Jan '15 - Don't Build a Distributed Monolit...
 
CocoaConf: The Language of Mobile Software is APIs
CocoaConf: The Language of Mobile Software is APIsCocoaConf: The Language of Mobile Software is APIs
CocoaConf: The Language of Mobile Software is APIs
 
What I learned about APIs in my first year at Google
What I learned about APIs in my first year at GoogleWhat I learned about APIs in my first year at Google
What I learned about APIs in my first year at Google
 
You need Event Mesh, not Service Mesh - Chris Suszynski [WJUG 301]
You need Event Mesh, not Service Mesh - Chris Suszynski [WJUG 301]You need Event Mesh, not Service Mesh - Chris Suszynski [WJUG 301]
You need Event Mesh, not Service Mesh - Chris Suszynski [WJUG 301]
 
The Future of Messaging: RabbitMQ and AMQP
The Future of Messaging: RabbitMQ and AMQP The Future of Messaging: RabbitMQ and AMQP
The Future of Messaging: RabbitMQ and AMQP
 
WMQ, WMB and EIP
WMQ, WMB and EIPWMQ, WMB and EIP
WMQ, WMB and EIP
 
Elegant Systems Integration w/ Apache Camel
Elegant Systems Integration w/ Apache CamelElegant Systems Integration w/ Apache Camel
Elegant Systems Integration w/ Apache Camel
 
Architecture | The Future of Messaging: RabbitMQ and AMQP | Eberhard Wolff
Architecture | The Future of Messaging: RabbitMQ and AMQP | Eberhard WolffArchitecture | The Future of Messaging: RabbitMQ and AMQP | Eberhard Wolff
Architecture | The Future of Messaging: RabbitMQ and AMQP | Eberhard Wolff
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the way
 
Why actor-based systems are the best for microservices
Why actor-based systems are the best for microservicesWhy actor-based systems are the best for microservices
Why actor-based systems are the best for microservices
 
MQTT, Eclipse Paho and Java - Messaging for the Internet of Things
MQTT, Eclipse Paho and Java - Messaging for the Internet of ThingsMQTT, Eclipse Paho and Java - Messaging for the Internet of Things
MQTT, Eclipse Paho and Java - Messaging for the Internet of Things
 
Messaging with RabbitMQ and AMQP
Messaging with RabbitMQ and AMQPMessaging with RabbitMQ and AMQP
Messaging with RabbitMQ and AMQP
 
Of the variedtypes of IPC, sockets arout and awaythe foremostcommon..pdf
Of the variedtypes of IPC, sockets arout and awaythe foremostcommon..pdfOf the variedtypes of IPC, sockets arout and awaythe foremostcommon..pdf
Of the variedtypes of IPC, sockets arout and awaythe foremostcommon..pdf
 
Splunk Conf 2014 - Getting the message
Splunk Conf 2014 - Getting the messageSplunk Conf 2014 - Getting the message
Splunk Conf 2014 - Getting the message
 
NoSQL afternoon in Japan Kumofs & MessagePack
NoSQL afternoon in Japan Kumofs & MessagePackNoSQL afternoon in Japan Kumofs & MessagePack
NoSQL afternoon in Japan Kumofs & MessagePack
 
NoSQL afternoon in Japan kumofs & MessagePack
NoSQL afternoon in Japan kumofs & MessagePackNoSQL afternoon in Japan kumofs & MessagePack
NoSQL afternoon in Japan kumofs & MessagePack
 
Down the RabbitMQ Hole
Down the RabbitMQ HoleDown the RabbitMQ Hole
Down the RabbitMQ Hole
 
Message queueing
Message queueingMessage queueing
Message queueing
 

Último

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Último (20)

Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdf
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 

Lindsay distributed geventzmq

  • 1. Distributed Systems with ZeroMQ and gevent Jeff Lindsay @progrium
  • 2. Why distributed systems? Harness more CPUs and resources Run faster in parallel Tolerance of individual failures Better separation of concerns
  • 3. Most web apps evolve into distributed systems
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 11. Amazon AWS Provider Web Provider API Client Provider TwiML
  • 12. ZeroMQ + gevent Two powerful and misunderstood tools
  • 14. Distributed computing is just another flavor of local concurrency
  • 15. Multithreading Shared Memory Thread Thread Thread Distributed system Shared Database App App App
  • 16. Concurrency models Execution model Defines the “computational unit” Communication model Means of sharing and coordination
  • 17. Concurrency models Traditional multithreading OS threads Shared memory, locks, etc Async or Evented I/O I/O loop + callback chains Shared memory, futures Actor model Shared nothing “processes” Built-in messaging
  • 18. Examples Erlang Actor model Scala Actor model Go Channels, Goroutines Everything else (Ruby, Python, PHP, Perl, C/C++, Java) Threading Evented
  • 19. Erlang is special. Normally, the networking of distributed systems is tacked on to the local concurrency model. MQ, RPC, REST, ...
  • 20. Why not always use Erlang?
  • 21. Why not always use Erlang? Half reasons Weird/ugly language Limited library ecosystem VM requires operational expertise Functional programming isn’t mainstream
  • 22. Why not always use Erlang? Half reasons Weird/ugly language Limited library ecosystem VM requires operational expertise Functional programming isn’t mainstream Biggest reason It’s not always the right tool for the job
  • 23. Amazon AWS Provider Web Provider API Client Provider TwiML
  • 24. Service Oriented Architecture Multiple languages Heterogeneous cluster
  • 25. RPC
  • 28. RPC Client / server Mapping to functions Message serialization
  • 29. RPC Client / server Mapping to functions Message serialization Poor abstraction of what you really want
  • 30. What you want are tools to help you get distributed actor model concurrency like Erlang ... without Erlang. Even better if they're decoupled and optional.
  • 31. Rarely will you build an application as part of a distributed system that does not also need local concurrency.
  • 32. Communication model How do we unify communications in local concurrency and distributed systems across languages?
  • 33. Execution model How do we get Erlang-style local concurrency without interfering with the language's idiomatic paradigm?
  • 37. Misconceptions It’s just another MQ, right? Not really.
  • 38. Misconceptions It’s just another MQ, right? Not really.
  • 39. Misconceptions It’s just another MQ, right? Not really. Oh, it’s just sockets, right?
  • 40. Misconceptions It’s just another MQ, right? Not really. Oh, it’s just sockets, right? Not really.
  • 41. Misconceptions It’s just another MQ, right? Not really. Oh, it’s just sockets, right? Not really.
  • 42. Misconceptions It’s just another MQ, right? Not really. Oh, it’s just sockets, right? Not really. Wait, isn’t messaging a solved problem?
  • 43. Misconceptions It’s just another MQ, right? Not really. Oh, it’s just sockets, right? Not really. Wait, isn’t messaging a solved problem? *sigh* ... maybe.
  • 46. Regular Sockets Point to point Stream of bytes
  • 47. Regular Sockets Point to point Stream of bytes Buffering
  • 48. Regular Sockets Point to point Stream of bytes Buffering Standard API
  • 49. Regular Sockets Point to point Stream of bytes Buffering Standard API TCP/IP or UDP, IPC
  • 55. Messaging Messages are atomic Messages can be routed
  • 56. Messaging Messages are atomic Messages can be routed
  • 57. Messaging Messages are atomic Messages can be routed
  • 58. Messaging Messages are atomic Messages can be routed Messages may sit around
  • 59. Messaging Messages are atomic Messages can be routed Messages may sit around
  • 60. Messaging Messages are atomic Messages can be routed Messages may sit around
  • 61. Messaging Messages are atomic Messages can be routed Messages may sit around
  • 62. Messaging Messages are atomic Messages can be routed Messages may sit around
  • 63. Messaging Messages are atomic Messages can be routed Messages may sit around
  • 64. Messaging Messages are atomic Messages can be routed Messages may sit around Messages are delivered
  • 65. Messaging Messages are atomic Messages can be routed Messages may sit around Messages are delivered
  • 66. Rise of the Big MQ
  • 67. App App Reliable Message Broker Persistent Queues App App
  • 68. App App App App
  • 69. AMQP MQ Producer Consumer
  • 70. AMQP MQ Binding Producer X Consumer Exchange Queue
  • 71. AMQP MQ Producer X Consumer Exchange Queue
  • 74. AMQP Recipes Work queues Publish/Subscribe Distributing tasks among workers Sending to many consumers at once X
  • 75. AMQP Recipes Work queues Publish/Subscribe Distributing tasks among workers Sending to many consumers at once X Routing Receiving messages selectively foo X bar baz
  • 76. AMQP Recipes Work queues Publish/Subscribe Distributing tasks among workers Sending to many consumers at once X Routing RPC Receiving messages selectively Remote procedure call implementation foo X bar baz
  • 77. Drawbacks of Big MQ Lots of complexity Queues are heavyweight HA is a challenge Poor primitives
  • 78. Enter ZeroMQ “Float like a butterfly, sting like a bee”
  • 79. Echo in Python Server Client 1 import zmq 1 import zmq 2 context = zmq.Context() 2 context = zmq.Context() 3 socket = context.socket(zmq.REP) 3 socket = context.socket(zmq.REQ) 4 socket.bind("tcp://127.0.0.1:5000") 4 socket.connect("tcp://127.0.0.1:5000") 5 5 6 while True: 6 for i in range(10): 7 msg = socket.recv() 7 msg = "msg %s" % i 8 print "Received", msg 8 socket.send(msg) 9 socket.send(msg) 9 print "Sending", msg 10 reply = socket.recv()
  • 80. Echo in Ruby Server Client 1 require "zmq" 1 require "zmq" 2 context = ZMQ::Context.new(1) 2 context = ZMQ::Context.new(1) 3 socket = context.socket(ZMQ::REP) 3 socket = context.socket(ZMQ::REQ) 4 socket.bind("tcp://127.0.0.1:5000") 4 socket.connect("tcp://127.0.0.1:5000") 5 5 6 loop do 6 (0...10).each do |i| 7 msg = socket.recv 7 msg = "msg #{i}" 8 puts "Received #{msg}" 8 socket.send(msg) 9 socket.send(msg) 9 puts "Sending #{msg}" 10 end 10 reply = socket.recv 11 end
  • 81. Echo in PHP Server Client 1 <?php 1 <?php 2 $context = new ZMQContext(); 2 $context = new ZMQContext(); 3 $socket = $context->getSocket(ZMQ::SOCKET_REP); 3 $socket = $context->getSocket(ZMQ::SOCKET_REQ); 4 $socket->bind("tcp://127.0.0.1:5000"); 4 $socket->connect("tcp://127.0.0.1:5000"); 5 5 6 while (true) { 6 foreach (range(0, 9) as $i) { 7 $msg = $socket->recv(); 7 $msg = "msg {$i}"; 8 echo "Received {$msg}"; 8 $socket->send($msg); 9 $socket->send($msg); 9 echo "Sending {$msg}"; 10 } 10 $reply = $socket->recv(); 11 ?> 11 } 12 ?>
  • 82. Bindings ActionScript, Ada, Bash, Basic, C, Chicken Scheme, Common Lisp, C#, C++, D, Erlang, F#, Go, Guile, Haskell, Haxe, Java, JavaScript, Lua, Node.js, Objective-C, Objective Caml, ooc, Perl, PHP, Python, Racket, REBOL, Red, Ruby, Smalltalk
  • 89. Plumbing inproc ipc tcp multicast socket.bind("tcp://localhost:5560") socket.bind("ipc:///tmp/this-socket") socket.connect("tcp://10.0.0.100:9000") socket.connect("ipc:///tmp/another-socket") socket.connect("inproc://another-socket")
  • 90. Plumbing inproc ipc tcp multicast socket.bind("tcp://localhost:5560") socket.bind("ipc:///tmp/this-socket") socket.connect("tcp://10.0.0.100:9000") socket.connect("ipc:///tmp/another-socket") socket.connect("inproc://another-socket")
  • 91. Plumbing inproc ipc tcp multicast socket.bind("tcp://localhost:5560") socket.bind("ipc:///tmp/this-socket") socket.connect("tcp://10.0.0.100:9000") socket.connect("ipc:///tmp/another-socket") socket.connect("inproc://another-socket")
  • 98. Message Patterns Request-Reply Publish-Subscribe REP SUB REQ REP PUB SUB REP SUB
  • 99. Message Patterns Request-Reply Publish-Subscribe REP SUB REQ REP PUB SUB REP SUB Push-Pull (Pipelining) PULL PUSH PULL PULL
  • 100. Message Patterns Request-Reply Publish-Subscribe REP SUB REQ REP PUB SUB REP SUB Push-Pull (Pipelining) PULL PUSH PULL PULL
  • 101. Message Patterns Request-Reply Publish-Subscribe REP SUB REQ REP PUB SUB REP SUB Push-Pull (Pipelining) PULL PUSH PULL PULL
  • 102. Message Patterns Request-Reply Publish-Subscribe REP SUB REQ REP PUB SUB REP SUB Push-Pull (Pipelining) PULL PUSH PULL PULL
  • 103. Message Patterns Request-Reply Publish-Subscribe REP SUB REQ REP PUB SUB REP SUB Push-Pull (Pipelining) Pair PULL PULL PAIR PAIR PUSH PULL
  • 104. Devices Queue Forwarder Streamer Design architectures around devices.
  • 105. Devices Queue Forwarder Streamer REQ REP Design architectures around devices.
  • 106. Devices Queue Forwarder Streamer PUB SUB Design architectures around devices.
  • 107. Devices Queue Forwarder Streamer PUSH PULL Design architectures around devices.
  • 109. Performance Orders of magnitude faster than most MQs
  • 110. Performance Orders of magnitude faster than most MQs Higher throughput than raw sockets
  • 111. Performance Orders of magnitude faster than most MQs Higher throughput than raw sockets Intelligent message batching
  • 112. Performance Orders of magnitude faster than most MQs Higher throughput than raw sockets Intelligent message batching Edge case optimizations
  • 113. Concurrency? "Come for the messaging, stay for the easy concurrency"
  • 114. Hintjens’ Law of Concurrency e= mc 2 E is effort, the pain that it takes M is mass, the size of the code C is conflict, when C threads collide
  • 115. Hintjens’ Law of Concurrency
  • 116. Hintjens’ Law of Concurrency
  • 117. Hintjens’ Law of Concurrency ZeroMQ: e=mc 2, for c=1
  • 118. ZeroMQ Easy ... familiar socket API Cheap ... lightweight queues in a library Fast ... higher throughput than raw TCP Expressive ... maps to your architecture Messaging toolkit for concurrency and distributed systems.
  • 120. Threading vs Evented Evented seems to be preferred for scalable I/O applications
  • 121. Evented Stack Non-blocking Code Flow Control I/O Abstraction Reactor I/O Loop Event Poller
  • 122. 1 def lookup(country, search_term): 2 main_d = defer.Deferred() 3 4 def first_step(): 5 query = "http://www.google.%s/search?q=%s" % (country,search_term) 6 d = getPage(query) 7 d.addCallback(second_step, country) 8 d.addErrback(failure, country) 9 10 def second_step(content, country): 11 m = re.search('<div id="?res.*?href="(?P<url>http://[^"]+)"', 12 content, re.DOTALL) 13 if not m: 14 main_d.callback(None) 15 return 16 url = m.group('url') 17 d = getPage(url) 18 d.addCallback(third_step, country, url) 19 d.addErrback(failure, country) 20 21 def third_step(content, country, url): 22 m = re.search("<title>(.*?)</title>", content) 23 if m: 24 title = m.group(1) 25 main_d.callback(dict(url = url, title = title)) 26 else: 27 main_d.callback(dict(url=url, title="{not-specified}")) 28 29 def failure(e, country): 30 print ".%s FAILED: %s" % (country, str(e)) 31 main_d.callback(None) 32 33 first_step() 34 return main_d
  • 123. gevent “Regular” Python Greenlets Monkey patching Reactor / Event Poller
  • 124. Green threads “Threads” implemented in user space (VM, library)
  • 125. Monkey patching socket, ssl, threading, time
  • 129. Performance http://nichol.as
  • 130. Performance http://nichol.as
  • 131. Performance http://nichol.as
  • 132. Building a Networking App 1 #=== 2 # 1. Basic gevent TCP server 3 4 from gevent.server import StreamServer 5 6 def handle_tcp(socket, address): 7 print 'new tcp connection!' 8 while True: 9 socket.send('hellon') 10 gevent.sleep(1) 11 12 tcp_server = StreamServer(('127.0.0.1', 1234), handle_tcp) 13 tcp_server.serve_forever()
  • 133. 1 #=== 2 # 2. Basic gevent TCP server and WSGI server 3 4 from gevent.pywsgi import WSGIServer 5 from gevent.server import StreamServer 6 7 def handle_http(env, start_response): 8 start_response('200 OK', [('Content-Type', 'text/html')]) 9 print 'new http request!' 10 return ["hello world"] 11 12 def handle_tcp(socket, address): 13 print 'new tcp connection!' 14 while True: 15 socket.send('hellon') 16 gevent.sleep(1) 17 18 tcp_server = StreamServer(('127.0.0.1', 1234), handle_tcp) 19 tcp_server.start() 20 21 http_server = WSGIServer(('127.0.0.1', 8080), handle_http) 22 http_server.serve_forever()
  • 134. 1 from gevent.pywsgi import WSGIServer 2 from gevent.server import StreamServer 3 from gevent.socket import create_connection 4 5 def handle_http(env, start_response): 6 start_response('200 OK', [('Content-Type', 'text/html')]) 7 print 'new http request!' 8 return ["hello world"] 9 10 def handle_tcp(socket, address): 11 print 'new tcp connection!' 12 while True: 13 socket.send('hellon') 14 gevent.sleep(1) 15 16 def client_connect(address): 17 sockfile = create_connection(address).makefile() 18 while True: 19 line = sockfile.readline() # returns None on EOF 20 if line is not None: 21 print "<<<", line, 22 else: 23 break 24 25 tcp_server = StreamServer(('127.0.0.1', 1234), handle_tcp) 26 tcp_server.start() 27 28 gevent.spawn(client_connect, ('127.0.0.1', 1234)) 29 30 http_server = WSGIServer(('127.0.0.1', 8080), handle_http) 31 http_server.serve_forever()
  • 135. 1 from gevent.pywsgi import WSGIServer 2 from gevent.server import StreamServer 3 from gevent.socket import create_connection 4 5 def handle_http(env, start_response): 6 start_response('200 OK', [('Content-Type', 'text/html')]) 7 print 'new http request!' 8 return ["hello world"] 9 10 def handle_tcp(socket, address): 11 print 'new tcp connection!' 12 while True: 13 socket.send('hellon') 14 gevent.sleep(1) 15 16 def client_connect(address): 17 sockfile = create_connection(address).makefile() 18 while True: 19 line = sockfile.readline() # returns None on EOF 20 if line is not None: 21 print "<<<", line, 22 else: 23 break 24 25 tcp_server = StreamServer(('127.0.0.1', 1234), handle_tcp) 26 http_server = WSGIServer(('127.0.0.1', 8080), handle_http) 27 greenlets = [ 28 gevent.spawn(tcp_server.serve_forever), 29 gevent.spawn(http_server.serve_forever), 30 gevent.spawn(client_connect, ('127.0.0.1', 1234)), 31 ] 32 gevent.joinall(greenlets)
  • 137.
  • 138. 1 from gevent import spawn 2 from gevent_zeromq import zmq 3 4 context = zmq.Context() 5 6 def serve(): 7 socket = context.socket(zmq.REP) 8 socket.bind("tcp://localhost:5559") 9 while True: 10 message = socket.recv() 11 print "Received request: ", message 12 socket.send("World") 13 14 server = spawn(serve) 15 16 def client(): 17 socket = context.socket(zmq.REQ) 18 socket.connect("tcp://localhost:5559") 19 for request in range(10): 20 socket.send("Hello") 21 message = socket.recv() 22 print "Received reply ", request, "[", message, "]" 23 24 spawn(client).join()
  • 139. Actor model? Easy to implement, in whole or in part, optionally with ZeroMQ
  • 140.
  • 141. What is gevent missing?
  • 142. What is gevent missing? Documentation
  • 143. What is gevent missing? Documentation Application framework
  • 145. 1 from gevent.pywsgi import WSGIServer 2 from gevent.server import StreamServer 3 from gevent.socket import create_connection 4 5 def handle_http(env, start_response): 6 start_response('200 OK', [('Content-Type', 'text/html')]) 7 print 'new http request!' 8 return ["hello world"] 9 10 def handle_tcp(socket, address): 11 print 'new tcp connection!' 12 while True: 13 socket.send('hellon') 14 gevent.sleep(1) 15 16 def client_connect(address): 17 sockfile = create_connection(address).makefile() 18 while True: 19 line = sockfile.readline() # returns None on EOF 20 if line is not None: 21 print "<<<", line, 22 else: 23 break 24 25 tcp_server = StreamServer(('127.0.0.1', 1234), handle_tcp) 26 http_server = WSGIServer(('127.0.0.1', 8080), handle_http) 27 greenlets = [ 28 gevent.spawn(tcp_server.serve_forever), 29 gevent.spawn(http_server.serve_forever), 30 gevent.spawn(client_connect, ('127.0.0.1', 1234)), 31 ] 32 gevent.joinall(greenlets)
  • 146. 1 from gevent.pywsgi import WSGIServer 2 from gevent.server import StreamServer 3 from gevent.socket import create_connection 4 5 from gservice.core import Service 6 7 def handle_http(env, start_response): 8 start_response('200 OK', [('Content-Type', 'text/html')]) 9 print 'new http request!' 10 return ["hello world"] 11 12 def handle_tcp(socket, address): 13 print 'new tcp connection!' 14 while True: 15 socket.send('hellon') 16 gevent.sleep(1) 17 18 def client_connect(address): 19 sockfile = create_connection(address).makefile() 20 while True: 21 line = sockfile.readline() # returns None on EOF 22 if line is not None: 23 print "<<<", line, 24 else: 25 break 26 27 app = Service() 28 app.add_service(StreamServer(('127.0.0.1', 1234), handle_tcp)) 29 app.add_service(WSGIServer(('127.0.0.1', 8080), handle_http)) 30 app.add_service(TcpClient(('127.0.0.1', 1234), client_connect)) 31 app.serve_forever()
  • 147. 1 from gservice.core import Service 2 from gservice.config import Setting 3 4 class MyApplication(Service): 5 http_port = Setting('http_port') 6 tcp_port = Setting('tcp_port') 7 connect_address = Setting('connect_address') 8 9 def __init__(self): 10 self.add_service(WSGIServer(('127.0.0.1', self.http_port), self.handle_http)) 11 self.add_service(StreamServer(('127.0.0.1', self.tcp_port), self.handle_tcp)) 12 self.add_service(TcpClient(self.connect_address, self.client_connect)) 13 14 def client_connect(self, address): 15 sockfile = create_connection(address).makefile() 16 while True: 17 line = sockfile.readline() # returns None on EOF 18 if line is not None: 19 print "<<<", line, 20 else: 21 break 22 23 def handle_tcp(self, socket, address): 24 print 'new tcp connection!' 25 while True: 26 socket.send('hellon') 27 gevent.sleep(1) 28 29 def handle_http(self, env, start_response): 30 start_response('200 OK', [('Content-Type', 'text/html')]) 31 print 'new http request!' 32 return ["hello world"]
  • 148. 1 # example.conf.py 2 3 pidfile = 'example.pid' 4 logfile = 'example.log' 5 http_port = 8080 6 tcp_port = 1234 7 connect_address = ('127.0.0.1', 1234) 8 9 def service(): 10 from example import MyApplication 11 return MyApplication() # Run in the foreground gservice -C example.conf.py # Start service as daemon gservice -C example.conf.py start # Control service gservice -C example.conf.py restart gservice -C example.conf.py reload gservice -C example.conf.py stop # Run with overriding configuration gservice -C example.conf.py -X 'http_port = 7070'
  • 149. Generalizing gevent proves a model that can be implemented in almost any language that can implement an evented stack
  • 150. gevent Easy ... just normal Python Small ... only 25 modules Fast ... top performing server Compatible ... works with most libraries Futuristic evented platform for network applications.
  • 151. Raiden Lightning fast, scalable messaging https://github.com/progrium/raiden
  • 153. Conclusion Two very simple, but very powerful tools for distributed / concurrent systems