【问题标题】:Why is raw wsgi app slower than flask app?为什么原始 wsgi 应用程序比烧瓶应用程序慢?
【发布时间】:2016-02-23 20:42:13
【问题描述】:

我写了两个简单的应用程序,一个是像下面这样的原始 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 应用程序结果:

并发级别:10 测试时间:306.216 秒 每秒请求数:1.52 [#/sec](平均值) 每个请求的时间:6585.299 [ms](平均) 每个请求的时间:658.530 [ms](平均,所有并发请求) 连接时间(毫秒) 最小值平均值[+/-sd] 中值最大值 连接:0 0 0.4 0 7 处理:1084 6499 3050.3 5951 15963 等待:96 5222 3051.4 4577 15096 总计:1085 6500 3050.2 5951 15963 特定时间内服务的请求百分比(毫秒) 50% 5938 66% 7584 75% 8597 80% 9186 90% 10829 95% 12033 98% 13209 99% 14722 100% 15963(最长请求)

和烧瓶应用程序的:

并发级别:10 测试时间:19.909 秒 每秒请求数:502.28 [#/sec](平均) 每个请求的时间:19.909 [ms](平均值) 每个请求的时间:1.991 [ms](平均值,所有并发请求) 连接时间(毫秒) 最小值平均值[+/-sd] 中值最大值 连接:0 0 0.0 0 2 处理:3 20 9.0 19 87 等待:2 20 8.9 19 86 总计:3 20 9.0 19 87 特定时间内服务的请求百分比(毫秒) 50% 19 66% 23 75% 25 80% 27 90% 31 95% 36 98% 41 99% 45 100% 87(最长请求)

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

【问题讨论】:

  • 不要将requests.get('http://www.baidu.com') 用于这些应用程序的基准标记!这两个应用程序大部分时间都浪费在 Network IO 上。所以它不涉及任何事情。
  • @kxxoling 好的,但评论说我得到了相同的结果。
  • 你刚刚评论了return resp.content吗?我认为您还应该评论作业部分。
  • 另一方面,database fetch 也是一个 IO 动作,会以某种方式影响结果。
  • 其实我写了两个测试,一个做db connection,一个做requests,我在上面的代码中一起写了,只是为了简化问题,不好意思给大家搞糊涂了。

标签: flask wsgi gevent wsgiserver


【解决方案1】:

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

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

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% 时间,这似乎是合理的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-25
    • 1970-01-01
    • 2015-09-07
    • 2012-07-28
    • 1970-01-01
    • 2017-10-18
    • 2020-09-04
    • 2014-05-08
    相关资源
    最近更新 更多