在heroku平台上部署了一个简单的python应用程序:
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
Procfile:
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
如何阻止多个工作线程启动并仅启动一个?
答案 0 :(得分:3)
您所看到的是预期的行为。请注意,这些不是线程,而是子进程。默认情况下,gunicorn
是分叉服务器 - 为了处理并发请求,它会创建多个子进程。
您会看到两个工作进程,因为根据文档(https://devcenter.heroku.com/articles/python-gunicorn#basic-configuration),gunicorn
尊重WEB_CONCURRENCY
环境变量,在Heroku上似乎默认为两个。
您可以通过WEB_CONCURRENCY=2 heroku local
非常直接地在本地复制行为;注意两个工人的pids。然后在没有WEB_CONCURRENCY
变量的情况下运行它,你只会看到一个工人pid。
如果您确实希望将其限制为一个进程,则可以在.env文件中或通过WEB_CONCURRENCY
命令将heroku config:set
显式设置为1。但是,我建议反对 -
hit_counter
变量在第二个工作程序中根本不可见。WEB_CONCURRENCY
允许您的dyno处理多个并发请求。如果将其限制为1,则需要多个dynos来支持并发请求,并产生相关的Heroku费用。希望有所帮助。