- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我们在 heroku 上运行 django/gunicorn 服务器。我们的大多数用户所在的国家/地区的移动网络不是那么好,因此他们经常遇到不稳定的连接。
我们的大多数请求都是来自移动设备的“原始帖子”,而且似乎即使 POST 请求未完全传输,该请求也已被发送给 gunicorn 工作人员处理。当工作人员尝试处理请求并读取数据时,它只是挂起等待剩余数据。虽然这种行为对于在“流”模式下读取文件/图像数据是有意义的,但在我们的例子中没有意义,因为我们所有的帖子都相对较小,并且可以很容易地被 Web 服务器作为一个整体读取,然后才转发给我们的 gunicorn worker 。
当我们有许多这样的并行请求时,这种提前切换会带来麻烦——因为所有工作人员都可能被阻塞。目前我们通过增加 worker/dynos 的数量来解决这个问题,但成本很高。我找不到任何方法来强制 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)
以下是此示例缓慢请求的 New Relic 测量结果(这是一个包含 7K 数据的 POST)。读取 POST 占用了 99% 的方法时间....
最佳答案
在我看来,这里真正的问题是 gunicorn 正在阻塞。这是因为 gunicorn(默认情况下)使用同步 worker 来运行您的任务。这意味着当 Web 请求到达 gunicorn 时,它会阻塞,直到它返回响应——在您的情况下,会等待很长时间。
要解决此问题,您可以将 gevent 与 gunicorn 结合使用来执行非阻塞 IO。由于您的大部分时间都花在做 IO 的事情上,这将确保 gunicorn 可以并行处理更多的网络请求。
要将 gevent 与 gunicorn 一起使用,您需要安装 gevent (pip install -U gevent
),并通过添加更改 gunicorn 启动命令:gunicorn -k gevent
(这会告诉 gunicorn 使用 gevent 作为 worker)。
关于python - 当客户端连接不稳定时,在 heroku 上运行的 django 中的工作人员卡在岗位上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12194070/
我是一名优秀的程序员,十分优秀!