【发布时间】:2014-11-14 08:41:50
【问题描述】:
我有一个用 Flask 编写的 python 脚本,它需要一些准备工作(连接到数据库、获取一些其他资源等)才能真正接受请求。
我在带有 wsgi 的 Apache HTTPD 下使用它。阿帕奇配置:
WSGIDaemonProcess test user=<uid> group=<gid> threads=1 processes=4
WSGIScriptAlias /flask/test <path>/flask/test/data.wsgi process-group=test
而且运行良好:Apache 会启动 4 个完全独立的进程,每个进程都有自己的数据库连接。
我现在正在尝试切换到 uwsgi + nginx。 nginx 配置:
location /flask/test/ {
include uwsgi_params;
uwsgi_pass unix:/tmp/uwsgi.sock;
}
uwsgi:
uwsgi -s /tmp/uwsgi.sock --mount /flask/test=test.py --callable app --manage-script-name --processes=4 --master
简化脚本test.py:
from flask import Flask, Response
app = Flask(__name__)
def do_some_preparation():
print("Prepared!")
@app.route("/test")
def get_test():
return Response("test")
do_some_preparation()
if __name__ == "__main__":
app.run()
我希望看到“准备好了!” 4次输出。但是,uwsgi 不这样做,输出:
Python main interpreter initialized at 0x71a7b0
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 363800 bytes (355 KB) for 4 cores
*** Operational MODE: preforking ***
mounting test.py on /flask/test
Prepared! <======================================
WSGI app 0 (mountpoint='/flask/test') ready in 0 seconds ...
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 1212)
spawned uWSGI worker 1 (pid: 1216, cores: 1)
spawned uWSGI worker 2 (pid: 1217, cores: 1)
spawned uWSGI worker 3 (pid: 1218, cores: 1)
spawned uWSGI worker 4 (pid: 1219, cores: 1)
因此,在这个简化的示例中,uwsgi 生成了 4 个 worker,但只执行了一次 do_some_preparation()。在实际应用中,打开了几个数据库连接,显然这些连接被这4个进程重用并导致并发请求问题。
有没有办法告诉 uwsgi 产生几个完全独立的进程?
编辑:当然,我可以使用以下解决方法:
from flask import Flask, Response
app = Flask(__name__)
all_prepared = False
def do_some_preparation():
global all_prepared
all_prepared = True
print("Prepared!")
@app.route("/test")
def get_test():
if not all_prepared:
do_some_preparation()
return Response("test")
if __name__ == "__main__":
app.run()
但是我将不得不在每条路线中都放置这个“all_prepared”检查,这似乎不是一个好的解决方案。
【问题讨论】: