我正在对nginx->gunicorn->Django应用程序进行HTTP POST请求。 响应正文返回很快,但请求在大约 60 秒内没有完全完成。
通过"完全完成",我的意思是我尝试过的各种客户端(Chrome,wget,我正在构建的Android应用程序(表明请求仍在进行中,就像在等待更多数据一样。从Wireshark监听,我看到所有数据都很快到达,然后在60秒后ACK FIN终于来了。
本地开发服务器(./manage.py runserver
(上的相同POST请求可以快速执行。此外,它绕过nginx,直接对枪角兽快速执行。在 Apache/mod_wsgi 设置中也能快速运行。
GET 请求没有问题。即使是其他 POST 请求也可以。我知道的一个区别是这个特定的请求返回 201 而不是 200。
我认为这与Content-Length
标头、封闭与保持连接有关,但还不知道事情应该如何正常工作。
- 后端服务器(gunicorn(当前正在关闭连接,这是有道理的。
- 后端服务器应该包括
Content-Length header
,还是Transfer-encoding: chunked
?或者nginx应该能够在没有这些的情况下应对,并根据需要添加它们? - 我认为连接保持活动状态很好,不应该在nginx中禁用。
更新:nginx.conf
keepalive_timeout
设置为 0 解决了我的问题。但是,当然,保持活力已经消失了。我仍然不确定问题出在哪里。堆栈中的某些内容(我的 Django 应用程序或 gunicorn(可能没有正确实现分块传输,并使客户端感到困惑。
您的上游服务器(gunicorn(以某种方式在该特定的api调用上保持连接打开状态 - 我不知道为什么(我认为取决于您的代码(,但是nginx中的默认proxy_read_timeout
选项是60秒,因此由于某种原因,听起来没有收到此响应。
我使用非常相似的设置,并且通常不会注意到POST或任何其他请求的任何问题。
请注意,return HttpResponse(status=201)
之前曾给我带来问题 - 似乎 Django 更喜欢一个明确的空体:return HttpResponse("", status=201)
工作。我通常会在身体里设置一些我应该做的事情 - 这可能是需要注意的事情。