Jar*_*iuk 5 python django post heroku gunicorn
我们在heroku上运行django/gunicorn服务器.我们的大多数用户都位于移动网络不是那么好的国家,因此他们经常会有不稳定的连接.
我们的大多数请求都是来自移动设备的"原始帖子",似乎即使POST请求未完全传输,该请求也已被发送,由一名枪支工作人员处理.当工作人员试图处理请求并读取数据时,它只是挂起等待剩余的数据.虽然这种行为对于以"流"模式读取文件/图像数据是有意义的,但在我们的情况下没有任何意义,因为我们的所有帖子都相对较小,并且可以由Web服务器作为一个整体轻松读取,然后转发给我们的gunicorn工人.
当我们并行提出许多此类请求时,这种早期切换会导致麻烦 - 因为所有工作人员都可能被阻止.目前,我们通过增加工人/动力的数量来解决这个问题,但这是相当昂贵的.我找不到任何方法强制web服务器或gunicorn等待,只有在完全传输后才将请求转发给工作人员.
有没有办法让heroku的web服务器/ gunicorn只在从客户端完全传输(由服务器完全接收)时将请求转移给gunicorn worker?
一些示例代码(我们添加了newrelic'per-instruction'跟踪以确保这是导致问题的确切行):
def syncGameState(request):
transaction = agent.current_transaction()
with agent.FunctionTrace(transaction, "syncGameState_raw_post_data", 'Python/EndPoint'):
data = request.raw_post_data
with agent.FunctionTrace(transaction, "syncGameState_gameStateSyncRequest", 'Python/EndPoint'):
sync_request = sync_pb2.gameStateSyncRequest()
with agent.FunctionTrace(transaction, "syncGameState_ParseFromString", 'Python/EndPoint'):
sync_request.ParseFromString(data)
Run Code Online (Sandbox Code Playgroud)
以下是此示例慢速请求的新Relic测量值(它是一个带有7K数据的POST).阅读POST需要99%的方法时间....

在我看来,这里真正的问题是gunicorn正在阻塞。这是因为 Gunicorn(默认情况下)使用同步工作线程来运行您的任务。这意味着当一个网络请求到达gunicorn时,它会阻塞,直到它返回响应——在你的情况下,会阻塞很长时间。
为了解决这个问题,你可以使用gevent和gunicorn来进行非阻塞IO。由于您的大部分时间都花在 IO 上,这将确保 Gunicorn 可以并行处理更多的 Web 请求。
要将 gevent 与 Gunicorn 一起使用,您需要安装 gevent ( pip install -U gevent),并通过添加以下内容来更改 Gunicorn 启动命令:(gunicorn -k gevent这将告诉 Gunicorn 使用 gevent 作为工作程序)。
| 归档时间: |
|
| 查看次数: |
945 次 |
| 最近记录: |