我们最近在从客户端 javascript 发送到我们的服务器时遇到了一个非常奇怪但非常一致的延迟。
这是我们的技术栈,从前到后:
- 自定义 javascript 客户端代码
- 主干.js
- Custom Backbone.sync() implementation
- jQuery.ajax() (1.7.2)
- XmlHttpRequest
- 浏览器(已在 Firefox 和 Chrome 上验证)
- 互联网
- Nginx 前端
- Intranet(通过 Nginx
http://
上游) - Nginx 后端
- Gunicorn(通过 Nginx
unix://
上游套接字) - Django 1.4
- django-tastypie
(旁注:您是否曾对 Web 开发的复杂感到敬畏?)
这是事件的时间表:
- 客户端代码在新创建的 Backbone 上调用
.save()
APIModel
. - 我们的习惯
.sync()
蜿蜒到client.send()
它将新创建的对象分派(dispatch)到$.ajax()
. - 生成的 XmlHttpRequest POST。该请求出现在浏览器开发工具的网络 Pane 中,标记为待处理。
- HTTP 请求到达 Nginx,Nginx 将其路由到 django-tastypie 后端。
- Tastypie 迅速而完美地处理请求,创建资源,并返回 201 CREATED 响应,其中包含指向新资源的
Location
header 。 - Nginx 记录请求并(表面上)发送响应。
- 1.1 分钟过去了,在此期间请求在“网络” Pane 中仍被标记为待处理。
- 请求在浏览器的网络 Pane 中标记为完成。
- jQuery
xhr
触发成功处理程序 - 我们的自定义 API 客户端的 success handler检测到 201 响应代码并触发对位置的后续 GET 请求。
- 通常的事情发生了,GET 迅速响应,最外层的
$.Deferred()
对象解析,触发任何关联的客户端代码成功处理程序。
其他需要考虑的细节:
- 同一堆栈中的 GET 请求和 PUT 请求会迅速得到解决。
- 当通过专用 HTTP 客户端与最外层的 Nginx 直接交互时,与相关请求相同的 POST 请求会迅速得到解决。
- 删除特殊情况 201 处理程序和后续 GET 对该错误没有影响。
- 延迟总是 1.1 分钟。我使用
console.time()
确定延迟在 65,000 毫秒范围内变化。 - 延迟只出现在这个配置中。它不会出现在我们的开发设置中,它稍微简单一些。
我所做的未经证实的假设:
- 一旦 Nginx 记录了一个请求,响应就会系上蝴蝶结并连同手写的感谢信发送给客户。
- 这不是浏览器或 jQuery 中的错误。
请原谅我煞费苦心的细节,但我已尽最大努力消除变量,目前,我可以放心地说问题是以下之一:
- 宇宙物理结构的缺陷
- 我们思维的感知模型存在缺陷
- 我们还没有考虑的其他事情
我希望获得#3。有什么想法吗?
最佳答案
谜底揭晓!这是 Content-Length
header ,或者更确切地说,缺少 header 。 @MaxDounin 的想法是正确的,我只是没有完全遵循它。
启用 Django 的 django.middleware.http.ConditionalGetMiddleware
达到了目的。 (此中间件设置 Content-Length
header 。)
关于javascript - 浏览器和 Nginx 之间的 HTTP POST 神秘约 1 分钟延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12606898/