Flask使用WSGI部署以及压力测试

本文中涉及到的代码都在github上做了托管,github地址为:https://github.com/jiaxiaolei/my_flask_project

应用举例:

$ tree
.
├── flask_twisted.py
├── gevent_server.py
├── hello.py
├── README.md
├── start_gunicore.sh
├── start.sh
├── templates
│   └── hello.html
├── test
│   └── test_siege.sh
├── tornado_server.py

filename: hello.py

from flask import Flask, render_template
app = Flask(__name__)

@app.route('/')
@app.route('/<name>')
def index(name=None):
    return render_template('hello.html', name=name)

if __name__ == '__main__':
    app.run(host='0.0.0.0',port=13579, debug=False)

filename: start.sh

python hello.py

filename: templates/hello.html

from Flask</title>
{% if name %}
<h1>Hello {{ name }}!</h1>
{% else %}
<h1>Hello World!</h1>
{% endif %}

启动flask web server:

$ ./start.sh

127.0.0.1 - - [15/Aug/2017 22:06:54] "GET /3344 HTTP/1.1" 200 -
127.0.0.1 - - [15/Aug/2017 22:06:54] "GET /3344 HTTP/1.1" 200 -
127.0.0.1 - - [15/Aug/2017 22:06:54] "GET /3344 HTTP/1.1" 200 -
...

进行测试:

$ siege -c 1000 -r 100 -b http://127.0.0.1:13579/3344


HTTP/1.0 200     0.02 secs:      49 bytes ==> GET  /3344
HTTP/1.0 200     0.01 secs:      49 bytes ==> GET  /3344
HTTP/1.0 200     0.00 secs:      49 bytes ==> GET  /3344
[error] socket: -2136484096 connection timed out.: Connection timed out
[error] socket: 849221376 connection timed out.: Connection timed out
[error] socket: 1327605504 connection timed out.: Connection timed out
[error] socket: -2010593536 connection timed out.: Connection timed out
[error] socket: 1344390912 connection timed out.: Connection timed out
[error] socket: 1596172032 connection timed out.: Connection timed out
HTTP/1.0 200     0.00 secs:      49 bytes ==> GET  /3344
HTTP/1.0 200     0.00 secs:      49 bytes ==> GET  /3344
HTTP/1.0 200     0.00 secs:      49 bytes ==> GET  /3344
HTTP/1.0 200     0.00 secs:      49 bytes ==> GET  /3344
HTTP/1.0 200     0.01 secs:      49 bytes ==> GET  /3344
HTTP/1.0 200     0.01 secs:      49 bytes ==> GET  /3344
HTTP/1.0 200     0.01 secs:      49 bytes ==> GET  /3344


Transactions:              25361 hits
Availability:              99.45 %
Elapsed time:             261.27 secs
Data transferred:           1.19 MB
Response time:              1.30 secs
Transaction rate:          97.07 trans/sec
Throughput:             0.00 MB/sec
Concurrency:              126.50
Successful transactions:       25361
Failed transactions:             139
Longest transaction:          168.89
Shortest transaction:           0.03

NOTE: -2010593536 这些数字具体什么含义,没太明白。

再次测试一组:

Transactions:              25377 hits
Availability:              99.52 %
Elapsed time:             231.44 secs
Data transferred:           1.19 MB
Response time:              1.08 secs
Transaction rate:         109.65 trans/sec
Throughput:             0.01 MB/sec
Concurrency:              118.42
Successful transactions:       25377
Failed transactions:             123
Longest transaction:          114.46
Shortest transaction:           0.03

$ gunicorn -w 1 -b 127.0.0.1:13578 hello:app

[2017-08-16 12:33:04 +0000] [4088] [INFO] Starting gunicorn 19.7.1
[2017-08-16 12:33:04 +0000] [4088] [INFO] Listening at: http://127.0.0.1:13578 (4088)
[2017-08-16 12:33:04 +0000] [4088] [INFO] Using worker: sync
[2017-08-16 12:33:04 +0000] [4092] [INFO] Booting worker with pid: 4092
[2017-08-16 12:36:51 +0000] [4088] [CRITICAL] WORKER TIMEOUT (pid:4092)
[2017-08-16 12:36:51 +0000] [4092] [INFO] Worker exiting (pid: 4092)
[2017-08-16 12:36:51 +0000] [4812] [INFO] Booting worker with pid: 4812

NOTE: 在client 发起请求访问 server 端的时候, 屏幕没有日志输出。 这和之前遇到的 gunicore 会忽视原有flask 框架的操作日志一致。

$ siege -c 1000 -r 100 -b http://127.0.0.1:13578/3344

...
HTTP/1.1 200     0.01 secs:      49 bytes ==> GET  /3344
[error] socket: 631695104 connection timed out.: Connection timed out
[error] socket: 35813120 connection timed out.: Connection timed out
[error] socket: 1378645760 connection timed out.: Connection timed out
HTTP/1.1 200     0.02 secs:      49 bytes ==> GET  /3344
HTTP/1.1 200     0.02 secs:      49 bytes ==> GET  /3344
...

HTTP/1.1 200     0.01 secs:      49 bytes ==> GET  /3344
HTTP/1.1 200     0.02 secs:      49 bytes ==> GET  /3344
[error] socket: -459356416 connection timed out.: Connection timed out
[error] socket: 1328289536 connection timed out.: Connection timed out
...


Transactions:              25464 hits
Availability:              99.86 %
Elapsed time:             135.97 secs
Data transferred:           1.19 MB
Response time:              0.79 secs
Transaction rate:         187.28 trans/sec
Throughput:             0.01 MB/sec
Concurrency:              147.11
Successful transactions:       25464
Failed transactions:              36
Longest transaction:          120.95
Shortest transaction:           0.00

tornado

$ python tornado_server.py
[W 170816 12:49:26 server:27] [UOP] App is running on: localhost:5000
...
[I 170816 12:46:45 wsgi:355] 200 GET /3344 (127.0.0.1) 0.88ms
[I 170816 12:46:45 wsgi:355] 200 GET /3344 (127.0.0.1) 0.80ms
[I 170816 12:46:45 wsgi:355] 200 GET /3344 (127.0.0.1) 0.90ms
[I 170816 12:46:45 wsgi:355] 200 GET /3344 (127.0.0.1) 0.79ms
[I 170816 12:46:45 wsgi:355] 200 GET /3344 (127.0.0.1) 0.78ms
...

$ siege -c 1000 -r 100 -b http://127.0.0.1:5000/3344


...
HTTP/1.1 200     0.00 secs:      49 bytes ==> GET  /3344
HTTP/1.1 200     0.00 secs:      49 bytes ==> GET  /3344
HTTP/1.1 200     0.01 secs:      49 bytes ==> GET  /3344
HTTP/1.1 200     0.01 secs:      49 bytes ==> GET  /3344
...

Transactions:              25500 hits
Availability:             100.00 %
Elapsed time:              52.93 secs
Data transferred:           1.19 MB
Response time:              0.38 secs
Transaction rate:         481.77 trans/sec
Throughput:             0.02 MB/sec
Concurrency:              181.93
Successful transactions:       25500
Failed transactions:               0
Longest transaction:           52.31
Shortest transaction:           0.03

gevent:

$ python gevent_server.py
...
::ffff:127.0.0.1 - - [2017-08-16 13:01:51] "GET /3344 HTTP/1.1" 200 165 0.000486
::ffff:127.0.0.1 - - [2017-08-16 13:01:51] "GET /3344 HTTP/1.1" 200 165 0.000481
::ffff:127.0.0.1 - - [2017-08-16 13:01:51] "GET /3344 HTTP/1.1" 200 165 0.000474
::ffff:127.0.0.1 - - [2017-08-16 13:01:51] "GET /3344 HTTP/1.1" 200 165 0.000457
::ffff:127.0.0.1 - - [2017-08-16 13:01:51] "GET /3344 HTTP/1.1" 200 165 0.001040
::ffff:127.0.0.1 - - [2017-08-16 13:01:51] "GET /3344 HTTP/1.1" 200 165 0.000845
::ffff:127.0.0.1 - - [2017-08-16 13:01:51] "GET /3344 HTTP/1.1" 200 165 0.000814
::ffff:127.0.0.1 - - [2017-08-16 13:01:51] "GET /3344 HTTP/1.1" 200 165 0.000938
...

gevent 的日志(屏幕输出的内容)也不是太好。

$ siege -c 1000 -r 100 -b http://127.0.0.1:5000/3344



HTTP/1.1 200     0.00 secs:      49 bytes ==> GET  /3344
HTTP/1.1 200     0.00 secs:      49 bytes ==> GET  /3344

Transactions:              25500 hits
Availability:             100.00 %
Elapsed time:              25.74 secs
Data transferred:           1.19 MB
Response time:              0.23 secs
Transaction rate:         990.68 trans/sec
Throughput:             0.05 MB/sec
Concurrency:              226.40
Successful transactions:       25500
Failed transactions:               0
Longest transaction:            7.21
Shortest transaction:           0.01

twisted:

NOTE: 因为twisted 和 flask 集成没有调试通。这里使用了一个flask 插件flask-twisted.

$ python flask_twisted.py

# NOTE: 很不幸,屏幕没有任何信息输出。
$ siege -c 1000 -r 100 -b http://127.0.0.1:13579/3344

Transactions:              25500 hits
Availability:             100.00 %
Elapsed time:              73.40 secs
Data transferred:           1.19 MB
Response time:              0.72 secs
Transaction rate:         347.41 trans/sec
Throughput:             0.02 MB/sec
Concurrency:              250.12
Successful transactions:       25500
Failed transactions:               0
Longest transaction:            3.81
Shortest transaction:           0.02

总结

之前我在给Flask做WSGIServer 选型的时候选择了Tornado。
经过这次多种WSGI的使用比较和性能测试,验证了当时的选择是正确的。从性能和使用习惯上,都推荐选择Tornado.

扩展阅读

flask 四种wsgi方式对比(tornado,Gunicorn,Twisted,Gevent)
http://blog.csdn.net/marscrazy_90/article/details/41943211
简介:

使用了siege 做压力测试。
提供了启动脚本和测试脚本,但是具体的WSGI配合使用不详细。
我基于此做了完善。

独立 WSGI 容器
http://docs.jinkan.org/docs/flask/deploying/wsgi-standalone.html
简介:
flask 的说明文档。

Linux下四款Web服务器压力测试工具(http_load、webbench、ab、siege)介绍
http://www.cnblogs.com/shipengzhi/archive/2012/10/09/2716766.html
简介:

介绍了4种压力测试工具的使用方法,以及结果分析。

tornado.wsgi — Interoperability with other Python frameworks and servers
https://www.tornadoweb.org/en/stable/wsgi.html
简介:
介绍了tornado.wsgi为其他python web框架如何集成。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,478评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,825评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,482评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,726评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,633评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,018评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,168评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,320评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,264评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,288评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,995评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,587评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,909评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,284评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,862评论 2 339

推荐阅读更多精彩内容