FlaskPython WebFlask实践

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

2017-08-16  本文已影响1253人  jiaxiaolei

本文中涉及到的代码都在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 选型的时候选择了Tronado。
经过这次多种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种压力测试工具的使用方法,以及结果分析。

上一篇 下一篇

猜你喜欢

热点阅读