flask 比较灵活,部署时候可以选择多种wSGI容器。
这里主要对Gunicorn 和 Tornado 两张WSGI容器做比较。
#filename: run.py
# -*- coding: utf-8 -*-
from uop import create_app
from config import APP_ENV
if __name__ == '__main__':
app = create_app(APP_ENV)
app.run(host='0.0.0.0', debug=True)
命令行启动flask服务:
$ python run.py
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 244-749-765
172.28.32.53 - - [19/Jul/2017 09:26:42] "GET /api/iteminfo/iteminfoes/local/600212 HTTP/1.0" 200 -
172.28.32.53 - - [19/Jul/2017 09:26:44] "GET /api/resource/?user_id=600212 HTTP/1.0" 200 -
172.28.32.53 - - [19/Jul/2017 09:26:44] "GET /api/deployment/getDeploymentsByInitiator?initiator=%E8%B4%BE%E6%99%93%E7%A3%8A HTTP/1.0" 200 -
INFO:werkzeug:172.28.32.53 - - [19/Jul/2017 09:26:44] "GET /api/deployment/getDeploymentsByInitiator?initiator=%E8%B4%BE%E6%99%93%E7%A3%8A HTTP/1.0" 200 -
127.0.0.1 - - [25/Jul/2017 11:30:51] "GET /api/mpc_resource/mpc_resource_creater HTTP/1.1" 200 -
INFO:werkzeug:127.0.0.1 - - [25/Jul/2017 11:30:51] "GET /api/mpc_resource/mpc_resource_creater HTTP/1.1" 200 -
127.0.0.1 - - [25/Jul/2017 11:31:21] "GET /api/mpc_resource/mpc_resource_creater HTTP/1.1" 200 -
INFO:werkzeug:127.0.0.1 - - [25/Jul/2017 11:31:21] "GET /api/mpc_resource/mpc_resource_creater HTTP/1.1" 200 -
127.0.0.1 - - [25/Jul/2017 11:31:35] "GET /api/user/users/0753bf1a-5736-11e7-929a-fa163e9474c9 HTTP/1.1" 200 -
INFO:werkzeug:127.0.0.1 - - [25/Jul/2017 11:31:35] "GET /api/user/users/0753bf1a-5736-11e7-929a-fa163e9474c9 HTTP/1.1" 200 -
127.0.0.1 - - [25/Jul/2017 11:31:36] "GET /api/deploy_instance/deploy_instances?user_id=0753bf1a-5736-11e7-929a-fa163e9474c9 HTTP/1.1" 200 -
INFO:werkzeug:127.0.0.1 - - [25/Jul/2017 11:31:36] "GET /api/deploy_instance/deploy_instances?user_id=0753bf1a-5736-11e7-929a-fa163e9474c9 HTTP/1.1" 200 -
127.0.0.1 - - [25/Jul/2017 11:31:36] "GET /api/deploy_instance/deploy_instances?user_id=0753bf1a-5736-11e7-929a-fa163e9474c9 HTTP/1.1" 200 -
INFO:werkzeug:127.0.0.1 - - [25/Jul/2017 11:31:36] "GET /api/deploy_instance/deploy_instances?user_id=0753bf1a-5736-11e7-929a-fa163e9474c9 HTTP/1.1" 200 -
127.0.0.1 - - [25/Jul/2017 11:31:51] "GET /api/mpc_resource/mpc_resource_creater HTTP/1.1" 200 -
INFO:werkzeug:127.0.0.1 - - [25/Jul/2017 11:31:51] "GET /api/mpc_resource/mpc_resource_creater HTTP/1.1" 200 -
127.0.0.1 - - [25/Jul/2017 11:32:09] "GET /api/ip_manager/ip_managers HTTP/1.1" 200 -
INFO:werkzeug:127.0.0.1 - - [25/Jul/2017 11:32:09] "GET /api/ip_manager/ip_managers HTTP/1.1" 200 -
127.0.0.1 - - [25/Jul/2017 11:32:15] "GET /api/pool/pools HTTP/1.1" 200 -
INFO:werkzeug:127.0.0.1 - - [25/Jul/2017 11:32:15] "GET /api/pool/pools HTTP/1.1" 200 -
127.0.0.1 - - [25/Jul/2017 11:32:15] "GET /api/pool/getHosts?host=osnode011007.syswin.com&host=osnode011017.syswin.com&host=osnode011006.syswin.com&host=osnode011018.s
yswin.com&host=osnode011013.syswin.com&host=osnode011008.syswin.com&host=osnode011019.syswin.com&host=osnode011009.syswin.com&host=osnode011014.syswin.com&host=osnode0
11010.syswin.com&host=osnode011021.syswin.com&host=osnode011011.syswin.com&host=osnode011012.syswin.com&host=osnode011025.syswin.com&host=osnode011005.syswin.com&host=
osnode011033.syswin.com&host=osnode011029.syswin.com&host=osnode011022.syswin.com&host=osnode011028.syswin.com&host=osnode011024.syswin.com&host=osnode011020.syswin.co
m HTTP/1.1" 200 -
使用 Gunicorn 做WSGI容器:
#filename: wsgi.py
# -*- coding: utf-8 -*-
from flask import Flask
from uop import create_app
application = create_app('testing')
#application = create_app('default')
if __name__ == '__main__':
application.run()
使用gunicorn启动flask:
$ gunicorn -b 0.0.0.0:5000 wsgi:application
[2017-07-19 12:12:25 +0000] [28126] [INFO] Starting gunicorn 19.7.1
[2017-07-19 12:12:25 +0000] [28126] [INFO] Listening at: http://0.0.0.0:5000 (28126)
[2017-07-19 12:12:25 +0000] [28126] [INFO] Using worker: sync
[2017-07-19 12:12:25 +0000] [28131] [INFO] Booting worker with pid: 28131
/root/uop-backend_runtime/uop-backend/uop/auth/handler.py:21: ExtDeprecationWarning: Importing flask.ext.httpauth is deprecated, use flask_httpauth instead.
from flask.ext.httpauth import HTTPBasicAuth
屏幕没有任何输出,flask 框架自己的输出都没有了
配置gunicorn 的log_level 为debug
(uop_backend_runtime) [root@uop-test-0cf36b77-f909-4bf8-a728-eb82f379c6bf uop-backend]# /root/.virtualenvs/uop_backend_runtime/bin/gunicorn -b 0.0.0.0:5000 wsgi:application --log-level=debug
[2017-07-19 12:07:29 +0000] [28044] [DEBUG] Current configuration:
proxy_protocol: False
worker_connections: 1000
statsd_host: None
max_requests_jitter: 0
post_fork:
errorlog: -
enable_stdio_inheritance: False
worker_class: sync
ssl_version: 2
suppress_ragged_eofs: True
syslog: False
syslog_facility: user
when_ready:
pre_fork:
cert_reqs: 0
preload_app: False
keepalive: 2
accesslog: None
group: 0
graceful_timeout: 30
do_handshake_on_connect: False
spew: False
workers: 1
proc_name: None
sendfile: None
pidfile: None
umask: 0
on_reload:
pre_exec:
worker_tmp_dir: None
limit_request_fields: 100
pythonpath: None
on_exit:
config: None
logconfig: None
check_config: False
statsd_prefix:
secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}
reload_engine: auto
proxy_allow_ips: ['127.0.0.1']
pre_request:
post_request:
forwarded_allow_ips: ['127.0.0.1']
worker_int:
raw_paste_global_conf: []
threads: 1
max_requests: 0
chdir: /root/uop-backend_runtime/uop-backend
daemon: False
user: 0
limit_request_line: 4094
access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
certfile: None
on_starting:
post_worker_init:
child_exit:
worker_exit:
paste: None
default_proc_name: wsgi:application
syslog_addr: udp://localhost:514
syslog_prefix: None
ciphers: TLSv1
worker_abort:
worker_abort:
loglevel: debug
bind: ['0.0.0.0:5000']
raw_env: []
initgroups: False
capture_output: False
reload: False
limit_request_field_size: 8190
nworkers_changed:
timeout: 30
keyfile: None
ca_certs: None
tmp_upload_dir: None
backlog: 2048
logger_class: gunicorn.glogging.Logger
[2017-07-19 12:07:29 +0000] [28044] [INFO] Starting gunicorn 19.7.1
[2017-07-19 12:07:29 +0000] [28044] [DEBUG] Arbiter booted
[2017-07-19 12:07:29 +0000] [28044] [INFO] Listening at: http://0.0.0.0:5000 (28044)
[2017-07-19 12:07:29 +0000] [28044] [INFO] Using worker: sync
[2017-07-19 12:07:29 +0000] [28049] [INFO] Booting worker with pid: 28049
[2017-07-19 12:07:29 +0000] [28044] [DEBUG] 1 workers
/root/uop-backend_runtime/uop-backend/uop/auth/handler.py:21: ExtDeprecationWarning: Importing flask.ext.httpauth is deprecated, use flask_httpauth instead.
from flask.ext.httpauth import HTTPBasicAuth
[2017-07-19 12:07:46 +0000] [28049] [DEBUG] GET /api/iteminfo/iteminfoes/project_item
[2017-07-19 12:09:01 +0000] [28049] [DEBUG] GET /api/deployment/getDeploymentsByInitiator
出现了大量的调试信息,request 的日志也出现了,但是只有URL, 没有request中请求的的参数
tornado
# filename: run_tornado.py
# -*- coding: utf-8 -*-
from uop import create_app
from config import APP_ENV
from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from tornado.options import define, options
import logging
if __name__ == '__main__':
options.parse_command_line()
logging.info('[UOP] UOP is starting...')
app = create_app(APP_ENV)
http_server = HTTPServer(WSGIContainer(app))
http_server.listen(5000)
IOLoop.instance().start()
输出日志:
$ python run_tornado.py
[I 170719 08:44:14 run_tornado:15] [UOP] come into main
[I 170719 08:44:20 wsgi:355] 200 GET /api/iteminfo/iteminfoes/project_item?user_id=600212 (172.28.32.53) 6.31ms
[I 170719 08:44:28 wsgi:355] 200 GET /api/resource/?user_id=600212 (172.28.32.53) 9.28ms
[I 170719 08:44:28 handler:376] [UOP] come into uop/deployment/handler.py, args: {'initiator': '\xe8\xb4\xbe\xe6\x99\x93\xe7\xa3\x8a'}
[I 170719 08:44:28 wsgi:355] 200 GET /api/deployment/getDeploymentsByInitiator?initiator=%E8%B4%BE%E6%99%93%E7%A3%8A (172.28.32.53) 3.68ms
NOTE:
In [10]: print('\xe8\xb4\xbe\xe6\x99\x93\xe7\xa3\x8a')
贾晓磊
简要分析:
-
pyton run.py
的时候,flask 框架本身有一些日志会在屏幕输出。 - 使用gunicorn之后, flask自己的日志被“覆盖”了。
- 使用gunicorn开启日志debug模式,会生成一些日志,但是request 的日志不完整。
最终选了tornado做flask的WSGI容器。