UWSGI Django Init
Uwsgi在启动后会创建出多个worker进程来处理web请求,然而这里面的科技与狠活会让你一不小心就掉进坑里。
Master模式#
https://serverfault.com/questions/674496/what-does-the-master-option-actually-do-in-uwsgi
Uwsgi有一个master模式,在创建worker进程之前会先创建一个master进程,然后通过fork创建worker进程。
代码初始化#
在项目中不可避免会需要写一些初始化代码,例如启动一个线程定期从数据库中读取配置信息,或者在项目启动时将初始数据写入数据库。
Django里面每个app都有一个类可以在app加载完成后加入自己的代码进行初始化工作。
不幸的是这段代码会在uwsgi的master进程中运行,然后uwsgi会fork其它worker进程。
Thread#
在复制worker进程时,会删除master里面的全部线程!
如果代码在初始化阶段创建了一个线程在做一些事情,那么在所有的worker里面这个线程都不会存在。
但如果在创建了worker后再创建的线程则没有任何问题。
DB Connection#
如果在代码初始化时连接了数据库,那么这个连接状态会被fork到worker进程中。
Worker进程里面的其它代码再次访问数据库时,会复用这个连接,结果就会产生各种奇怪的数据库错误。
解决方案#
上面的问答中提到,通过设置:lazy-apps=true 可以避免在master进程中打开的数据库连接被带到worker进程中。
在实际项目中,通过设置lazy-apps解决了初始化时的各种奇怪的问题。