快乐学习
前程无忧、中华英才非你莫属!

Python-异步编程-gevent-12

Gevent ZeroMQ

ZeroMQ 被其作者描述为“充当并发框架的套接字库”。 它是一个非常强大的消息传递层,用于构建并发和分布式应用程序。

ZeroMQ 提供了多种套接字原语,其中最简单的是请求-响应套接字对。 套接字有两种感兴趣的方法 send 和 recv,这两种方法通常都是阻塞操作。 但这已由 Travis Cline 的一个出色的库(现在是 pyzmq 的一部分)进行了补救,该库使用 gevent.socket 以非阻塞方式轮询 ZeroMQ 套接字。

# Note: Remember to ``pip install pyzmq``
import gevent
import zmq.green as zmq

# Global Context
context = zmq.Context()

def server():
    server_socket = context.socket(zmq.REQ)
    server_socket.bind("tcp://127.0.0.1:5000")

    for request in range(1,10):
        server_socket.send("Hello")
        print('Switched to Server for %s' % request)
        # Implicit context switch occurs here
        server_socket.recv()

def client():
    client_socket = context.socket(zmq.REP)
    client_socket.connect("tcp://127.0.0.1:5000")

    for request in range(1,10):

        client_socket.recv()
        print('Switched to Client for %s' % request)
        # Implicit context switch occurs here
        client_socket.send("World")

publisher = gevent.spawn(server)
client    = gevent.spawn(client)

gevent.joinall([publisher, client])

Switched to Server for 1
Switched to Client for 1
Switched to Server for 2
Switched to Client for 2
Switched to Server for 3
Switched to Client for 3
Switched to Server for 4
Switched to Client for 4
Switched to Server for 5
Switched to Client for 5
Switched to Server for 6
Switched to Client for 6
Switched to Server for 7
Switched to Client for 7
Switched to Server for 8
Switched to Client for 8
Switched to Server for 9
Switched to Client for 9

Simple Servers

# On Unix: Access with ``$ nc 127.0.0.1 5000``
# On Window: Access with ``$ telnet 127.0.0.1 5000``

from gevent.server import StreamServer

def handle(socket, address):
    socket.send("Hello from a telnet!\n")
    for i in range(5):
        socket.send(str(i) + '\n')
    socket.close()

server = StreamServer(('127.0.0.1', 5000), handle)
server.serve_forever()

WSGI Servers

Gevent 提供了两个 WSGI 服务器,用于通过 HTTP 提供内容。 此后称为 wsgi 和 pywsgi:

gevent.wsgi.WSGIServer
gevent.pywsgi.WSGIServer
在 1.0.x 之前的早期 gevent 版本中,gevent 使用 libevent 而不是 libev。 Libevent 包含一个快速的 HTTP 服务器,它被 gevent 的 wsgi 服务器使用。

在 gevent 1.0.x 中没有包含 http 服务器。 相反,gevent.wsgi 现在是 gevent.pywsgi 中纯 Python 服务器的别名。

Streaming Servers

如果您使用的是 gevent 1.0.x,则本节不适用

对于那些熟悉流式 HTTP 服务的人来说,核心思想是在标头中我们不指定内容的长度。 相反,我们保持连接打开并沿管道冲洗块,在每个前面加上一个表示块长度的十六进制数字。 当发送大小为零的块时,流将关闭。

HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked

8
<p>Hello

9
World</p>

0

无法在 wsgi 中创建上述 HTTP 连接,因为不支持流式传输。 相反,它必须缓冲。

from gevent.wsgi import WSGIServer

def application(environ, start_response):
    status = '200 OK'
    body = '<p>Hello World</p>'

    headers = [
        ('Content-Type', 'text/html')
    ]

    start_response(status, headers)
    return [body]

WSGIServer(('', 8000), application).serve_forever()

然而,使用 pywsgi 我们可以将我们的处理程序编写为生成器并通过 chun 生成结果块

from gevent.pywsgi import WSGIServer

def application(environ, start_response):
    status = '200 OK'

    headers = [
        ('Content-Type', 'text/html')
    ]

    start_response(status, headers)
    yield "<p>Hello"
    yield "World</p>"

WSGIServer(('', 8000), application).serve_forever()

但无论如何,与其他 Python 服务器相比,Gevent 服务器的性能是惊人的。 libev 是一项经过严格审查的技术,众所周知,它的衍生服务器在规模上表现良好。

要进行基准测试,请尝试使用 Apache Benchmark ab 或查看 Python WSGI 服务器的基准以与其他服务器进行比较。

$ ab -n 10000 -c 100 http://127.0.0.1:8000/
打赏

未经允许不得转载:同乐学堂 » Python-异步编程-gevent-12

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

特别的技术,给特别的你!

联系QQ:1071235258QQ群:367203382
error: Sorry,暂时内容不可复制!