gunicorn+supervisor
1.gunicorn
安裝:
pip3 install gunicorn
配置:
兩種方式:命令和文件,因爲配置項比較多,所以放在文件裏,啓動時指明配置文件即可
命令:
如:gunicorn –w 4 –b 0.0.0.0:5000 –c config.py manager:app
-b 綁定應用的ip和端口
-w work的數量,官方說可以有:核心數*+1個
-c 指定配置文件
manager 入口程序文件,即manager.py
app manager中的flask對象
配置文件config.py:
import multiprocessing
import os# 如果沒有日誌目錄,創建一個;在當前gunicorn運行目錄
if not os.path.exists('log'):
os.mkdir('log')
debug = True
bind = '0.0.0.0:5000'
# pid文件爲文本文件,內容只有一行, 記錄了該進程的ID;
# 防止進程啓動多個副本。只有獲得pid文件(固定路徑固定文件名)寫入權限(F_WRLCK)的進程才能正常啓動並把自身的PID寫入該文件中。其它同一個程序的多餘進程則自動退出。
pidfile = 'log/gunicorn.pid'
loglevel = 'debug' # 日誌等級,與accesslog相關
logfile = 'log/gunicorn_debug.log' # debug日誌?實際沒有生成
errorlog = 'log/gunicorn_error.log' # 運行產生的具體日誌信息
accesslog = 'log/gunicorn_access.log' # 只有請求日誌,每個請求一條,包括請求的時間,大小,路徑
access_log_format = '%(h)s %(l)s %(p)s %(u)s %(t)s %(r)s %(s)s %(b)s %(f)s %(a)s %(D)s'
reload = True# 啓動的進程數
workers = multiprocessing.cpu_count()# 以何種方式處理請求
# (同步:sync),(異步:gevent/eventlet),(asyncIO:gthread/ gaiohttp),(tornado:tornado)
worker_class = 'gunicorn.workers.ggevent.GeventWorker'
x_forwarded_for_header = 'X-FORWARDED-FOR'
配置好後通過gunicorn –c config.py manager:app啓動
將flask日誌整合進gunicorn
這樣就不需要單獨存儲flask的日誌,最終只需要查看gunicorn記錄的flask日誌即可
if __name__ != '__main__':
# 如果不是直接運行,則將日誌輸出到 gunicorn 中# 會讀取gunicorn的日誌配置,如存放目錄、格式等
gunicorn_logger = logging.getLogger('gunicorn.error')
app.logger.handlers = gunicorn_logger.handlers
app.logger.setLevel(gunicorn_logger.level)
TODO
gunicorn各種模式的性能對比
2.supervisor
用於管理gunicorn,將其當作自己的子進程啓動;當gunicorn由於異常等停止運行後,supervisor可以自動重啓gunicorn
爲c/s架構,supervisord 是服務端,supervisorctl 是客戶端
supervisord啓動成功後,可以通過supervisorctl客戶端控制進程,啓動、停止、重啓
運行supervisorctl命令,不加參數,會進入supervisor客戶端的交互終端
安裝:
pip3 install supervisor
生成配置文件:
python3不支持生成配置的命令,所以需要再額外安裝python2的supervisor
然後在python3環境下使用python2生成的配置文件
sudo echo_supervisord_conf > /etc/supervisor/supervisord.conf
supervisord.conf即爲supervisor的配置文件
更改配置文件:(;表示註釋)
[unix_http_server]
;file=/tmp/supervisor.sock ;修改爲 /var/run 目錄,避免被系統刪除
file=/var/run/supervisor.sock
;socket文件的路徑,supervisorctl用XML_RPC和supervisord通信就是通過它進行的。如果不設置的話,supervisorctl也就不能用了
;chmod=0700,上面的socket文件的權限設置爲0700
[supervisord]
loglevel=debug ; 設置日誌等級,默認info,其他: critical, error, warn, info, debug, trace, or blather
;logfile=/tmp/supervisord.log ;修改爲 /var/log 目錄,避免被系統刪除
logfile= /home/user/python/flask_app/log/supervisord.log ;
; 這個是supervisord自身的日誌路徑,和子進程的日誌無關logfile_maxbytes=50MB ;日誌文件大小,默認50M
logfile_backups=10 ;當日志文件大於50M,會再創建一個,最多創建10個
;pidfile=/tmp/supervisord.pid ;修改爲 /var/run 目錄,避免被系統刪除
pidfile=/var/run/supervisord.pid
;nodaemon=false ; 如果是true,supervisord進程將在前臺運行,默認爲false,也就是後臺以守護進程運行
;設置可以管理supervisord的用戶,可以設置一個非root用戶,當以root用戶啓動supervisord之後,所設置的這個用戶也可以對supervisord進行管理
;user=chrism
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; 必須和[unix_http_server]裏面的file設定匹配
[include]
files = /etc/supervisor/conf.d/*.conf
;設置各進程的配置,使得每個進程有自己單獨的配置文件,即conf.d目錄下可以有多個conf文件,每個對應一個應用
更詳細的參考:https://www.cnblogs.com/justuntil/p/9843011.html
supervisor子進程(flask應用)配置
program:flask_app]
command=/home/user/python/python_virtual/flask_app/bin/gunicorn -c /home/user/python/flask_app/config_g.py manager:app
directory=/home/user/python/flask_app
stdout_logfile=/home/user/python/flask_app/log/supervisor_stdout.log
stderr_logfile=/home/user/python/flask_app/log/supervisor_stderr.log
autostart=true
autorestart=true
startsecs=10
priority=997