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进程里面的其它代码再次访问数据库时,会复用这个连接,结果就会产生各种奇怪的数据库错误。

解决方案#

https://stackoverflow.com/questions/25904817/ningx-uwsgi-python-permanent-mysql-error-after-some-time-from-starting-applica

上面的问答中提到,通过设置:lazy-apps=true 可以避免在master进程中打开的数据库连接被带到worker进程中。

在实际项目中,通过设置lazy-apps解决了初始化时的各种奇怪的问题。

comments powered by Disqus