浏览器和Nginx之间的HTTP POST延迟约1分钟,令人费解



我们最近在从客户端javascript发布到服务器时遇到了一个非常奇怪但非常一致的延迟。

这是我们的技术堆栈,从前到后:

  1. 自定义javascript客户端代码
  2. Backbone.js
  3. 自定义Backbone.sync()实现
  4. jQuery.ajax()(1.7.2)
  5. XmlHttpRequest
  6. 浏览器(已在Firefox和Chrome上验证)
  7. 互联网
  8. Nginx前端
  9. 内联网(通过Nginxhttp://上游)
  10. Nginx后端
  11. Gunicorn(通过Nginxunix://上游插座)
  12. Django 1.4
  13. django tastypie

(旁注:你有没有对复杂的web开发感到敬畏?)

以下是事件的时间表:

  1. 客户端代码在新创建的主干APIModel上调用.save()
  2. 我们的自定义.sync()迂回到client.send(),后者将新创建的对象分派到$.ajax()
  3. 生成的XmlHttpRequest POST。该请求显示在浏览器开发工具的"网络"窗格中,标记为挂起
  4. HTTP请求到达Nginx,后者将其路由到django-tastypie后端
  5. Tastypie迅速而完美地处理请求,创建资源,并返回201 CREATED响应,其中Location标头指向新资源
  6. Nginx记录请求并(表面上)发送响应
  7. 1.1分钟后,在此期间,请求仍在"网络"窗格中标记为挂起
  8. 该请求在浏览器的"网络"窗格中标记为完成
  9. jQueryxhr触发成功处理程序
  10. 我们定制的API客户端的成功处理程序检测到201响应代码,并向Location发出后续的GET请求
  11. 通常情况下,GET会迅速响应,最外层的$.Deferred()对象会解析,从而触发任何相关的客户端代码成功处理程序

其他需要考虑的细节:

  1. 同一堆栈中的GET请求和PUT请求会迅速解析
  2. 当通过专用的HTTP客户端直接与最外层的Nginx交互时,与所讨论的请求相同的POST请求会迅速解决
  3. 删除特殊情况201处理程序和随后的GET对错误没有影响
  4. 延迟总是1.1分钟。我已经使用console.time()来确定延迟在65000ms范围内变化
  5. 延迟仅在此配置中出现。它不会出现在我们的开发设置中,因为我们的开发稍微简单一些

我所做的未经验证的假设:

  1. 一旦Nginx记录了一个请求,响应就会被鞠躬绑起来,并发送给客户一张手写的感谢信
  2. 这不是浏览器或jQuery中的错误

请原谅这个煞费苦心的细节,但我已经尽了最大努力消除了变量,目前,我可以放心地说,问题是以下之一:

  1. 宇宙物理结构中的一个缺陷
  2. 我们头脑感知模型中的一个缺陷
  3. 其他我们还没有考虑的事情

我希望获得第三名。有什么想法吗?

谜团解开!这是Content-Length的标题,或者更确切地说,缺少一个@MaxDounin有一个正确的想法,我只是做得不够深入。

启用Django的django.middleware.http.ConditionalGetMiddleware成功了。(此中间件设置Content-Length标头。)

最新更新