uwsgi相关

Python项目中,一般是nginx + uwsgi的形式进行部署

简单实用

启动

uwsgi –ini uwsgi.ini

停止

uwsgi –stop uwsgi.pid

重载

uwsgi –reload uwsgi.pid

配置

项目中实际配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
[uwsgi]
callable = application  # uwsgi入口
wsgi-file = wsgi.py     # 加载wsgi文件
master = true  # 启用master进程
processes = 4 # 生成指定数目的worker/进程
socket = /tmp/classapi.sock # 使用默认协议绑定到指定UNIX/TCP socket上
chmod-socket = 666 # 设置sock读写权限, 默认为666
vacuum = true # 进程挂掉后, 自动删除unix socket文件和pid文件
daemonize = /tmp/app.log  # 使进程在后台运行,并将日志打到指定的日志文件
die-on-term = true # 进程手动杀死后,不自动重载
pidfile = /tmp/classapi.pid # 创建pid文件
gevent = 100 # 启用gevent协程 提高并发请求
env = LANG=en_US.UTF-8 # 设置环境变量
buffer-size = 32768 # 设置内部缓冲大小
log-maxsize= 524288000 # 日志达到500M后进行自动切割
disable-logging = true # uwsgi请求相关的日志不记录
log-master = true  # 将写入 log 的工作委托给 master 进程
threaded-log = true # 单独开一个线程进行 log 写入工作,这样有更好的性能

关于uwsgi日志和业务日志混用的问题 debug模式下开启StreamHandler,其余模式只使用FileHandler

参考 https://blog.zengrong.net/post/flask-uwsgi-logging/

启动方式分析

  1. pre-fork

    master进程 完成init操作,然后fork worker进程

  2. lazy_app

    master进程 先fork worker进程, 各worker完成init

比较: lazy_app比较耗费内存

Pre-forked helloworld app with 10 workers = 46M. The same app with lazy-apps = yes = 225MB. So, even two full copies of pre-forked app (92MB) are way better than lazy-apps (depending on number of workers).

重载方式分析

1. re-exec master (“r”)

1.master立即停止掉worker 2.等待所有worker挂掉 3.master重新初始化,在同一进程中运行新的实例 4.spawn新的worker

问题: 第一步中空闲的worker会立即杀死,只有busy的worker会保留。 在第二步中需要等待较长时间, 无法处理新的请求 在第三步中,也无法处理新的请求

服务down机耗时: busy-shutdown + init 服务切换耗时: busy-shutdown + init master是否重启:是

2. restart workers (“w”)

1.master立即停止掉worker 2.当一个worker挂掉后,立即重新spawn新worker 3.等待所有worker re-spawn

问题: master不必等待所有worker挂掉,空闲worker die/spawn都是异步 只会重启worker

服务down机耗时: idle-shutdown + init (新worker spawn后即可处理新请求) 服务切换耗时: busy-shutdown + init master是否重启: 否 (不能与pre-fork启动方式配合使用,pre-fork方式启动,worker和master共享init内存)

3. chain restart workers (“c”)

1.master按照某种顺序依次杀掉worker 2.当一个worker挂掉后,立即re-spawn 3.直到所有的worker re-spawn

问题: master按照某种顺序依次杀掉,整个过程耗时O(N) 存在new/old混合存在的worker,新的请求有可能被 new/old worker处理

服务down机耗时: 0 (新旧worker共存,均可服务,不存在down机情况) 服务切换耗时: N x (busy-shutdown + init) master是否重启: 否 (不能与pre-fork启动方式配合使用)

4. fork master (“f”)

1.fork新的master 2.当新的master初始化完成,fork新的worker 3.old master被通知停掉 4.old master会存活,直到busy worker结束

total time: ~ init + busy-shutdown 服务down机耗时: 0 (新旧worker共存,均可服务,不存在down机情况) 服务切换耗时: init + busy-shutdown 问题: master fork自身,内存中保存两份拷贝, 比较耗时内存,new/old worker混合

master是否重启: 否

方案选择

down机耗时: r/w方式,必须shut down后restart服务,r拥有最长耗时 pre-fork支持: w/c方式不支持 mixed responses: c方式new worker和old worker同时存活 memory heavy: f方式比较耗费内存

参考: http://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/WSGIquickstart.html

http://zarnovican.github.io/2016/02/15/uwsgi-graceful-reload/

https://blog.csdn.net/orangleliu/article/details/48437319