Flask很是容易上手,它自帶的app.run(host="0.0.0.0", port=7001)
用來調試很是方便,可是用於生產環境不管是處理高併發仍是魯棒性都有所欠缺,通常會配合WGSI容器來進行[生產環境的部署][1]。python
小磊哥推薦了參考文章[1]中的部署方式,但願將已有的服務放到gunicorn或者Tornado中部署,並用supervisor來管理全部進程(有幾個不一樣的服務)。flask
通過調研和嘗試安全
首先pip安裝gunicorn。
pip install gunicorn --user
bash
因爲是部署在公司雲主機上,一般不會給root權限。以前都是提工單給SA sudo裝的,後來發現更安全也更方便的方法是pip install xxx --user
,美中不足是安裝完之後須要手動添加PATH
export PATH=/home/username/.local/bin:$PATH
方便起見能夠加到~/.bash_profile
中併發
簡單地,gunicorn能夠經過gunicorn -w 4 -b 127.0.0.1:4000 run:app
啓動一個Flask應用。其中,app
-w 4
是指預約義的工做進程數爲4,-b 127.0.0.1:4000
指綁定地址和端口其中run.py中文件的可能形式是:高併發
# run.py from flask import Flask app = Flask(__name__)
經過gunicorn -h
能夠看到gunicorn有很是多的配置項,所以一般會寫成一個config.py文件來進行配置。看了一下文檔彷佛沒有給出正確的config.py中配置項的命名,而且有些博客博主給出的配置項命名是錯誤的,致使配置沒有生效,踩了很多的坑(我找不到那篇坑坑的文章了)。這篇博客[2]給出了一些比較經常使用且正確的配置。post
我所用項目的配置項以下:性能
# config.py import os import gevent.monkey gevent.monkey.patch_all() import multiprocessing # debug = True loglevel = 'debug' bind = "0.0.0.0:7001" pidfile = "log/gunicorn.pid" accesslog = "log/access.log" errorlog = "log/debug.log" daemon = True # 啓動的進程數 workers = multiprocessing.cpu_count() worker_class = 'gevent' x_forwarded_for_header = 'X-FORWARDED-FOR'
生產環境不須要這個配置項,但調試的時候仍是挺好用的。並且,開啓debug項後,在啓動gunicorn的時候能夠看到全部可配置項的配置,以下所示。
以前在被上一篇博主欺騙的時候,仔細看了調試信息,發現accesslog和errorlog都沒有被配置,因此致使啓動之後看不到任何日誌。spa
config.py中只須要配置須要修改的項的,大部分採用默認配置便可。默認配置的具體配置內容能夠經過gunicorn -h
來查詢。
*配置文件和調試信息來自兩個不一樣進程,所以信息可能有細微差別
# Debug Info [2018-01-18 17:38:47 +0000] [16015] [DEBUG] Current configuration: proxy_protocol: False worker_connections: 1000 statsd_host: None max_requests_jitter: 0 post_fork: <function post_fork at 0x21037d0> errorlog: - enable_stdio_inheritance: False worker_class: gunicorn.workers.ggevent.GeventWorker ssl_version: 2 suppress_ragged_eofs: True syslog: False syslog_facility: user when_ready: <function when_ready at 0x2103500> pre_fork: <function pre_fork at 0x2103668> cert_reqs: 0 preload_app: False keepalive: 2 accesslog: log/debug.log group: 1001 graceful_timeout: 30 do_handshake_on_connect: False spew: False workers: 2 proc_name: None sendfile: None pidfile: log/gunicorn.pid umask: 0 on_reload: <function on_reload at 0x2103398> pre_exec: <function pre_exec at 0x2103d70> worker_tmp_dir: None limit_request_fields: 100 pythonpath: None on_exit: <function on_exit at 0x21065f0> config: gunicorn_conf.py 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 0x2103ed8> post_request: <function post_request at 0x2106050> forwarded_allow_ips: ['127.0.0.1'] worker_int: <function worker_int at 0x2103aa0> raw_paste_global_conf: [] threads: 1 max_requests: 0 chdir: /home/hzyangxiao2014/POPORobot/QASP daemon: False user: 1028 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 0x2103230> post_worker_init: <function post_worker_init at 0x2103938> child_exit: <function child_exit at 0x21061b8> worker_exit: <function worker_exit at 0x2106320> paste: None default_proc_name: run:app syslog_addr: udp://localhost:514 syslog_prefix: None ciphers: TLSv1 worker_abort: <function worker_abort at 0x2103c08> loglevel: debug bind: ['0.0.0.0:7001'] raw_env: [] initgroups: False capture_output: False reload: False limit_request_field_size: 8190 nworkers_changed: <function nworkers_changed at 0x2106488> timeout: 30 keyfile: None ca_certs: None tmp_upload_dir: None backlog: 2048 logger_class: gunicorn.glogging.Logger
# config.py accesslog = "log/access.log" errorlog = "log/debug.log" loglevel = "debug"
worker_class是指開啓的每一個工做進程的模式類型,默認爲sync模式,也可以使用gevent模式。
workers
是工做進程數量,在上述config.py
中,取的是CPU的數量。須要注意部署機器的性能,不能無限制多開。多篇文章中推薦了multiprocessing.cpu_count() * 2 + 1
這個數量,考慮到我會在一個機器上部署兩個服務,所以數量減半。
daemon = True
意味着開啓後臺運行,默認爲False
gunicorn的環境配置和使用都比較簡單,也解決了我老是用nohup python run.py >out.log 2>&1 &來啓動Flask後臺服務的問題。
在採用gunicorn部署以前,我也對後臺服務的目錄結構進行了調整。雖然只是便利工做的服務,也但願能夠儘量變的更加professional~
原文連接:https://www.jianshu.com/p/fecf15ad0c9a來源:簡書