Python Web

Flask部署时WSGI容器选型

2017-07-19  本文已影响60人  jiaxiaolei

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: <function post_fork at 0x2936938>
  errorlog: -
  enable_stdio_inheritance: False
  worker_class: sync
  ssl_version: 2
  suppress_ragged_eofs: True
  syslog: False
  syslog_facility: user
  when_ready: <function when_ready at 0x2936668>
  pre_fork: <function pre_fork at 0x29367d0>
  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: <function on_reload at 0x2936500>
  pre_exec: <function pre_exec at 0x2936ed8>
  worker_tmp_dir: None
  limit_request_fields: 100
  pythonpath: None
  on_exit: <function on_exit at 0x293b758>
  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: <function pre_request at 0x293b0c8>
  post_request: <function post_request at 0x293b1b8>
  forwarded_allow_ips: ['127.0.0.1']
  worker_int: <function worker_int at 0x2936c08>
  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: <function on_starting at 0x2936398>
  post_worker_init: <function post_worker_init at 0x2936aa0>
  child_exit: <function child_exit at 0x293b320>
  worker_exit: <function worker_exit at 0x293b488>
  paste: None
  default_proc_name: wsgi:application
  syslog_addr: udp://localhost:514
  syslog_prefix: None
  ciphers: TLSv1
  worker_abort: <function worker_abort at 0x2936d70>
  worker_abort: <function worker_abort at 0x2936d70>
  loglevel: debug
  bind: ['0.0.0.0:5000']
  raw_env: []
  initgroups: False
  capture_output: False
  reload: False
  limit_request_field_size: 8190
  nworkers_changed: <function nworkers_changed at 0x293b5f0>
  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')
贾晓磊

简要分析:

  1. pyton run.py的时候,flask 框架本身有一些日志会在屏幕输出。
  2. 使用gunicorn之后, flask自己的日志被“覆盖”了。
  3. 使用gunicorn开启日志debug模式,会生成一些日志,但是request 的日志不完整。

最终选了tornado做flask的WSGI容器。

上一篇下一篇

猜你喜欢

热点阅读