有一个简单的Python应用程序部署在heroku平台上:
from flask import Flask
log("APP STARTED.")
# single time connection to database and logging stuff
app = Flask(__name__)
@app.route('/', methods=['GET'])
# do something
@app.route('/', methods=['POST'])
# do something
过程文件:
web: gunicorn app:app --log-file=-
在查看日志时,我发现上面的代码使用多个线程多次执行。我知道由于日志记录不一致,肯定涉及更多线程。查看日志:
2017-05-31T17:12:46.415059+00:00 app[web.1]: APP STARTED.
2017-05-31T17:12:46.415072+00:00 app[web.1]: Executing query.
2017-05-31T17:12:46.415688+00:00 app[web.1]: APP STARTED.
2017-05-31T17:12:46.415717+00:00 app[web.1]: Executing query.
2017-05-31T17:12:46.436370+00:00 app[web.1]: Successful connection to database.
2017-05-31T17:12:46.437398+00:00 app[web.1]: Successful connection to database.
2017-05-31T17:12:46.439197+00:00 app[web.1]: Success executing query.
2017-05-31T17:12:46.439680+00:00 app[web.1]: Success executing query.
我还可以在这里看到工作线程:
2017-05-31T18:59:10.046388+00:00 app[web.1]: [2017-05-31 18:59:10 +0000] [9] [INFO] Booting worker with pid: 9
2017-05-31T18:59:10.132547+00:00 app[web.1]: [2017-05-31 18:59:10 +0000] [11] [INFO] Booting worker with pid: 11
如何防止多个工作线程启动并仅从一个启动?
您所看到的是预期行为。请注意,这些不是线程,而是子进程。默认情况下,gunicorn
是一个分叉服务器 - 为了处理并发请求,它创建多个子进程。
您会看到两个工作进程,因为根据文档(https://devcenter.heroku.com/articles/python-gunicorn#basic-configuration https://devcenter.heroku.com/articles/python-gunicorn#basic-configuration), gunicorn
荣誉WEB_CONCURRENCY
环境变量,在 Heroku 上似乎默认为 2。
您可以非常直接地在本地复制该行为,通过WEB_CONCURRENCY=2 heroku local
;记下两个工作进程 pid。然后运行它,无需WEB_CONCURRENCY
变量,你只会看到一个工人 pid。
如果你真的想将其限制为一个进程,你可以显式设置WEB_CONCURRENCY
到 1,无论是在 .env 文件中还是通过heroku config:set
命令。不过,我建议不要这样做——
- 由于它们是进程而不是线程,因此线程同步不是问题。需要注意的是,您不能依赖共享状态(例如,更新模块级变量)。例如,一个
hit_counter
在一个工作人员中实现的变量在第二个工作人员中根本不可见。
- 并发性within测功机将帮助您更经济有效地扩展规模。
WEB_CONCURRENCY
大于 1 可以让您的 dyno 处理多个并发请求。如果将其限制为 1,则需要多个 dyno 来支持并发请求,并产生相关的 Heroku 费用。
希望有帮助。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)