zoukankan      html  css  js  c++  java
  • gunicorn

    我们看gunicorn文档可以得知,gunicorn是一个python编写的高效的WSGI HTTP服务器,gunicorn使用pre-fork模型(一个master进程管理多个child子进程),使用gunicorn的方法十分简单:

    gunicorn --workers=9 server:app --bind 127.0.0.1:8000

    根据文档说明使用(2 * cpu核心数量)+1个worker,还要传入一个兼容wsgi app的start up方法,通过Flask的源码可以看到,Flask这个类实现了下面这个接口:

        def __call__(self, environ, start_response):
            """Shortcut for :attr:`wsgi_app`."""
            return self.wsgi_app(environ, start_response)

    也就是说我们只需把flask实例的名字传给gunicorn就ok了:

    gunicorn --workers=9 server:app --bind 127.0.0.1:8000
    [2017-01-27 11:20:01 +0800] [5855] [INFO] Starting gunicorn 19.6.0
    [2017-01-27 11:20:01 +0800] [5855] [INFO] Listening at: http://127.0.0.1:8000 (5855)
    [2017-01-27 11:20:01 +0800] [5855] [INFO] Using worker: sync
    [2017-01-27 11:20:01 +0800] [5889] [INFO] Booting worker with pid: 5889
    [2017-01-27 11:20:01 +0800] [5890] [INFO] Booting worker with pid: 5890
    [2017-01-27 11:20:01 +0800] [5891] [INFO] Booting worker with pid: 5891
    [2017-01-27 11:20:01 +0800] [5892] [INFO] Booting worker with pid: 5892
    [2017-01-27 11:20:02 +0800] [5893] [INFO] Booting worker with pid: 5893
    [2017-01-27 11:20:02 +0800] [5894] [INFO] Booting worker with pid: 5894
    [2017-01-27 11:20:02 +0800] [5895] [INFO] Booting worker with pid: 5895
    [2017-01-27 11:20:02 +0800] [5896] [INFO] Booting worker with pid: 5896
    [2017-01-27 11:20:02 +0800] [5897] [INFO] Booting worker with pid: 5897

    可以看到gunicorn启动了9个进程(其中1个父进程)监听请求。使用了多进程的模型看起来是下面这样的:


    继续进行性能测试,可以看到吞吐量又有了很大的提升:

    wrk -c 100 -t 12 -d 5s http://127.0.0.1:8000/todo
    Running 5s test @ http://127.0.0.1:8000/todo
      12 threads and 100 connections
      Thread Stats   Avg      Stdev     Max   +/- Stdev
        Latency   109.30ms   16.10ms 251.01ms   90.31%
        Req/Sec    72.47     10.48   100.00     78.89%
      4373 requests in 5.07s, 6.59MB read
    Requests/sec:    863.35
    Transfer/sec:      1.30MB

    那么gunicorn还能再优化吗,答案是肯定的。回到之前我们发现了这一行:

    [2017-01-27 11:20:01 +0800] [5855] [INFO] Using worker: sync

    也就是说,gunicorn worker使用的是sync(同步)模式来处理请求,那么它支持async(异步)模式吗,再看gunicorn的文档有下面一段说明:

    Async Workers
    The asynchronous workers available are based on Greenlets (via Eventlet and Gevent). Greenlets are an implementation of cooperative multi-threading for Python. In general, an application should be able to make use of these worker classes with no changes.

    gunicorn支持基于greenlet的异步的worker,它使得worker能够协作式地工作。当worker阻塞在外部调用的IO操作时,gunicorn会聪明地把执行调度给其他worker,挂起当前的worker,直至IO操作完成后,被挂起的worker又会重新加入到调度队列中,这样gunicorn便有能力处理大量的并发请求了。

    gunicorn有两个不错的async worker:

    • meinheld
    • gevent

    meinheld是一个基于picoev的异步WSGI Web服务器,它可以很轻松地集成到gunicorn中,处理wsgi请求。

    gunicorn --workers=9 --worker-class="meinheld.gmeinheld.MeinheldWorker" server:app --bind 127.0.0.1:8000
    [2017-01-27 11:47:01 +0800] [7497] [INFO] Starting gunicorn 19.6.0
    [2017-01-27 11:47:01 +0800] [7497] [INFO] Listening at: http://127.0.0.1:8000 (7497)
    [2017-01-27 11:47:01 +0800] [7497] [INFO] Using worker: meinheld.gmeinheld.MeinheldWorker
    [2017-01-27 11:47:01 +0800] [7531] [INFO] Booting worker with pid: 7531
    [2017-01-27 11:47:01 +0800] [7532] [INFO] Booting worker with pid: 7532
    [2017-01-27 11:47:01 +0800] [7533] [INFO] Booting worker with pid: 7533
    [2017-01-27 11:47:01 +0800] [7534] [INFO] Booting worker with pid: 7534
    [2017-01-27 11:47:01 +0800] [7535] [INFO] Booting worker with pid: 7535
    [2017-01-27 11:47:01 +0800] [7536] [INFO] Booting worker with pid: 7536
    [2017-01-27 11:47:01 +0800] [7537] [INFO] Booting worker with pid: 7537
    [2017-01-27 11:47:01 +0800] [7538] [INFO] Booting worker with pid: 7538
    [2017-01-27 11:47:01 +0800] [7539] [INFO] Booting worker with pid: 7539

    可以看到现在使用的是meinheld.gmeinheld.MeinheldWorker这个worker。再进行性能测试看看:

    wrk -c 100 -t 12 -d 5s http://127.0.0.1:8000/todo
    Running 5s test @ http://127.0.0.1:8000/todo
      12 threads and 100 connections
      Thread Stats   Avg      Stdev     Max   +/- Stdev
        Latency    84.53ms   39.90ms 354.42ms   72.11%
        Req/Sec    94.52     20.84   150.00     70.28%
      5684 requests in 5.04s, 8.59MB read
    Requests/sec:   1128.72
    Transfer/sec:      1.71MB

    果然提升了不少。

  • 相关阅读:
    前端 CSS
    前端 HTML
    前端 JavaScript 初识
    网络编程——线程池
    网络编程——同一进程中的队列(多线程)
    网络编程——进程间的共享内存
    vue实现前端简易版模糊查询
    封装axios请求拦截器
    关于node中 mysql Client does not support authentication protocol requested by server; consider upgrading MySQL client 解决方法
    封装一个时间方法
  • 原文地址:https://www.cnblogs.com/liuye1990/p/13182180.html
Copyright © 2011-2022 走看看