为什么原始wsgi应用程序比烧瓶应用程序慢?

时间:2015-11-21 10:35:12

标签: flask wsgi gevent wsgiserver

我编写了两个简单的应用程序,一个是原始的wsgi应用程序,如下所示,另一个是使用Flask构建的,并且都运行在gevent wsgi服务器上。
当应用程序中没有网络连接时,正如我预期的那样,原始wsgi应用程序比烧瓶应用程序更快,但是当应用程序中有一些网络连接时,原始wsgi应用程序比烧瓶应用程序慢得多。

原始

import json
from gevent import monkey
monkey.patch_all() # monkey patch for both apps

import pymysql
conn = pymysql.connect(host=HOST,port=PORT,...,cursorclass=pymysql.cursors.DictCursor) 

import requests

def application(environ, start_response):
    # database connection
    cur = conn.cursor()
    cur.execute('select * from food')
    res = cur.fetchall()

    # requests
    resp = requests.get('http://www.baidu.com')

    start_response('200 OK', [('Content-Type', 'application')])
    return json.dumps(res)
    # return resp.content
from gevent.wsgi import WSGIServer
http_server = WSGIServer(('', 8080), application)
http_server.serve_forever()

烧瓶

from gevent import monkey
monkey.patch_all()
import json
from flask import Flask
app = Flask(__name__)

conn = pymysql.connect(host=HOST,port=PORT,...,cursorclass=pymysql.cursors.DictCursor)
@app.route('/')
def index():
    # database connection
    cur = conn.cursor()
    cur.execute('select * from food')
    res = cur.fetchall()

    # requests
    resp = requests.get('http://www.baidu.com')
    return json.dumps(res), 200
from gevent.wsgi import WSGIServer
http_server = WSGIServer(('', 8080), app)
http_server.serve_forever()

我使用ab进行基准测试:

$ ab -c10 -n10000 http://127.0.0.1:8080/

这是原始的wsgi app结果:

    Concurrency Level:      10
    Time taken for tests:   306.216 seconds
    Requests per second:    1.52 [#/sec] (mean)
    Time per request:       6585.299 [ms] (mean)
    Time per request:       658.530 [ms] (mean, across all concurrent requests)

    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Connect:        0    0   0.4      0       7
    Processing:  1084 6499 3050.3   5951   15963
    Waiting:       96 5222 3051.4   4577   15096
    Total:       1085 6500 3050.2   5951   15963

    Percentage of the requests served within a certain time (ms)
      50%   5938
      66%   7584
      75%   8597
      80%   9186
      90%  10829
      95%  12033
      98%  13209
      99%  14722
     100%  15963 (longest request)

和烧瓶应用程序:

    Concurrency Level:      10
    Time taken for tests:   19.909 seconds
    Requests per second:    502.28 [#/sec] (mean)
    Time per request:       19.909 [ms] (mean)
    Time per request:       1.991 [ms] (mean, across all concurrent requests)

    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Connect:        0    0   0.0      0       2
    Processing:     3   20   9.0     19      87
    Waiting:        2   20   8.9     19      86
    Total:          3   20   9.0     19      87

    Percentage of the requests served within a certain time (ms)
      50%     19
      66%     23
      75%     25
      80%     27
      90%     31
      95%     36
      98%     41
      99%     45
     100%     87 (longest request)

所以我想知道烧瓶做了什么,我怎么做才能更快地使用没有框架的简单wsgi应用程序?

1 个答案:

答案 0 :(得分:1)

我认为你的问题不存在。您所犯的最大错误是引入了IO部分(网络IO和磁盘IO),这与Web框架的性能无关。

为了证明这一点,我将你的演示简化为:

import json
from gevent import monkey
monkey.patch_all() # monkey patch for both apps

def application(environ, start_response):    
    res = dict(hello='world')

    start_response('200 OK', [('Content-Type', 'application')])
    return json.dumps(res)

from gevent.wsgi import WSGIServer
http_server = WSGIServer(('', 8088), application)
http_server.serve_forever()

from gevent import monkey
monkey.patch_all()
import json
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    res = dict(hello='world')
    return json.dumps(res), 200

from gevent.wsgi import WSGIServer

http_server = WSGIServer(('', 8088), app)
http_server.serve_forever()

原始WSGI的结果是:

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       5
Processing:     1    5   0.7      5      23
Waiting:        1    5   0.7      5      23
Total:          1    6   0.7      5      24
WARNING: The median and mean for the total time are not within a normal deviation
        These results are probably not that reliable.

Percentage of the requests served within a certain time (ms)
  50%      5
  66%      6
  75%      6
  80%      6
  90%      6
  95%      6
  98%      7
  99%      8
 100%     24 (longest request)

对于Flask来说:

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       1
Processing:     1    6   0.6      6      11
Waiting:        1    6   0.6      6      11
Total:          2    6   0.6      6      11

Percentage of the requests served within a certain time (ms)
  50%      6
  66%      6
  75%      6
  80%      6
  90%      7
  95%      7
  98%      7
  99%      8
 100%     11 (longest request)

忽略最长的1%请求,您可以发现原始WSGI比Flask快20%,这似乎是合理的。