Gunicorn“绿色独角兽”是一个被普遍使用的高性能的Python WSGI UNIX HTTP服务器,移植自Ruby的独角兽(Unicorn )项目,使用pre-fork worker模式,具备使用很是简单,轻量级的资源消耗,以及高性能等特色。django
Gunicorn 服务器做为wsgi app的容器,可以与各类Web框架兼容(flask,django等),得益于gevent等技术,使用Gunicorn可以在基本不改变wsgi app代码的前提下,大幅度提升wsgi app的性能。flask
gunicorn pre-fork worker模型中有一个管理进程以及几个的工做进程。管理进程:master,工做进程:worker。(如下代码中为了方面理解,均去除了一些干扰代码)服务器
master经过pre-fork的方式建立多个worker:网络
在worker.init_process()函数中,worker中gunicorn的app对象会去import 咱们的wsgi app。也就是说,每一个woker子进程都会单独去实例化咱们的wsgi app对象。每一个worker中的swgi app对象是相互独立、互不干扰的。app
manager维护数量固定的worker:框架
建立完全部的worker后,worker和master各自进入本身的消息循环。
master的事件循环就是收收信号,管理管理worker进程,而worker进程的事件循环就是监听网络事件并处理(如新建链接,断开链接,处理请求发送响应等等),因此真正的链接最终是连到了worker进程上的。(注:有关这种多进程模型的详细介绍,能够参考http://blog.csdn.net/largetalk/article/details/7939080)socket
woker有不少种,包括:ggevent、geventlet、gtornado等等。这里主要分析ggevent。函数
每一个ggevent worker启动的时候会启动多个server对象:worker首先为每一个listener建立一个server对象(注:为何是一组listener,由于gunicorn能够绑定一组地址,每一个地址对于一个listener),每一个server对象都有运行在一个单独的gevent pool对象中。真正等待连接和处理连接的操做是在server对象中进行的。tornado
上面代码中的server_class其实是一个gevent的WSGI SERVER的子类:性能
须要注意的是构造PyWSGIServer的参数:
这些参数中s是server用来监听连接的套接字。spawn是gevent的协程池。application便是咱们的wsgi app(通俗点讲就是你用 flask 或者 django写成的app),咱们的app就是经过这种方式交给gunicorn的woker去跑的。 handler_class是gevent的pywsgi.WSGIHandler子类。
当全部server对象建立完毕后,worker须要定时通知manager,不然会被认为是挂掉了。
这个地方的notify机制设计的比较有趣,每一个worker有个与之对应的tmp file,每次notify的时候去操做一下这个tmp file(好比经过os.fchmod),这个tmp file的last update的时间戳就会更新。而manager则经过检查每一个worker对应的temp file的last update的时间戳,来判断这个进程是不是挂掉的。
真正等待连接和处理连接的操做是在gevent的WSGIServer 和 WSGIHandler中进行的。
最后再来看一下gevent的WSGIServer 和 WSGIHandler的主要实现:
WSGIServer 的start函数里面调用start_accepting来处理到来的连接。在start_accepting里面获得接收到的套接字后调用do_handle来处理套接字:
能够看出,WSGIServer 其实是建立一个协程去处理该套接字,也就是说在WSGIServer 中,一个协程单独负责一个HTTP连接。协程中运行的self._handle函数其实是调用了WSGIHandler的handle函数来不断处理http 请求:
在handle函数的循环内部,handle_one_request函数首先读取HTTP 请求,初始化WSGI环境,而后最终调用run_application函数来处理请求:
在这个地方才真正的调用了咱们的 app。
总结:gunicorn 会启动一组 worker进程,全部worker进程公用一组listener,在每一个worker中为每一个listener创建一个wsgi server。每当有HTTP连接到来时,wsgi server建立一个协程来处理该连接,协程处理该连接的时候,先初始化WSGI环境,而后调用用户提供的app对象去处理HTTP请求。