Django应用程序在Heroku上运行时,当客户端连接不稳定时,工作者挂在发送后。

2024-10-01 15:45:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我们正在heroku上运行django/gunicorn服务器。我们的大多数用户都在一个移动网络不太好的国家,因此他们经常有不稳定的连接。在

我们的大多数请求都是来自移动设备的“原始帖子”,而且似乎即使POST请求没有被完全传输,请求也已经被发送出去,由gunicorn的工作人员处理。当worker尝试处理请求并读取数据时,它只是挂起等待剩余的数据。虽然这种行为对于以“流式”模式读取文件/图像数据是有意义的,但在我们的案例中却没有任何意义,因为我们所有的帖子都相对较小,很容易被整个web服务器读取,然后才转发给我们的gunicorn工作人员。在

当我们同时有许多这样的请求时,这种早期的切换会带来麻烦,因为所有的工作人员都可能会被阻塞。目前我们通过增加工人/dynos的数量来解决这个问题,但这是相当昂贵的。我找不到任何方法来强制web服务器或gunicorn等待请求,只在请求被完全传输后才转发给工作人员。在

有没有办法让heroku的web服务器/gunicorn只在请求从客户端完全传输(由服务器完全接收)时将请求传输给gunicorn工作人员吗?在

一些示例代码(我们添加了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)

下面是这个示例slow请求的newrelic度量(它是一个包含7K数据的POST)。阅读帖子需要99%的方法时间。。。。在

enter image description here


Tags: 数据服务器webdatarequestwithsyncendpoint
2条回答

在我看来,这里真正的问题是古尼康正在阻止。这是因为gunicorn(默认情况下)使用同步工作者来运行您的任务。这意味着,当一个web请求命中gunicorn时,它将阻塞,直到它在您的案例中返回响应为止,时间很长。在

为了解决这个问题,可以使用gevent和gunicorn来执行非阻塞IO。因为你的大部分时间都花在了IO上,这将确保gunicorn可以并行处理更多的web请求。在

要在gunicorn中使用gevent,您需要安装gevent(pip install -U gevent),并通过添加:gunicorn -k gevent来更改gunicorn的启动命令(这将告诉gunicorn将gevent用作worker)。在

You might want to give this article a read并调查请求缓冲HTTP服务器,如服务员。在

相关问题 更多 >

    热门问题