Flask部署时WSGI容器选型

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容器。

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

推荐阅读更多精彩内容

  • [TOC]一直想做源码阅读这件事,总感觉难度太高时间太少,可望不可见。最近正好时间充裕,决定试试做一下,并记录一下...
    何柯君阅读 7,185评论 3 98
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,652评论 18 139
  • 作者:詹聪聪 序言: 本人工作中需要用到flask-socketio,在学习英文文档时发现,flask-socke...
    Python中文社区阅读 12,647评论 6 39
  • 夏日炎炎天气热,阳光似火户外烧。无风无雨树悄静,闲着没事品茶香。泉靓水甜茶汤纯,美点肴正心相怡。清茶浊酒迎宾客,点...
    甘朝武阅读 67评论 0 0
  • 简书日语学习交流群新版打卡活动第二期第一天 话题为相对词应用,需要学员整理下列单词的基本含义、用法、以及与其他单词...
    白子童阅读 393评论 0 0