5

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

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

  1. 自定义 javascript 客户端代码
  2. 骨干网.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. 姜戈 1.4
  13. django-tastypie

(旁注:您是否曾经对Web 开发的复杂性感到敬畏?)

这是事件的时间表:

  1. 客户端代码调用.save()新创建的 Backbone APIModel
  2. 我们的自定义.sync()方式client.send()将新创建的对象分派到$.ajax().
  3. 生成的 XmlHttpRequest POST。该请求出现在浏览器开发工具的 Network 窗格中,标记为pending
  4. HTTP 请求到达 Nginx,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()确定延迟在 65,000 毫秒范围内变化。
  5. 延迟仅出现在此配置中。它不会出现在我们稍微简单的开发设置中。

我正在做的未经证实的假设:

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

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

  1. 宇宙物理结构的缺陷
  2. 我们心智感知模型的缺陷
  3. 我们还没有考虑过的其他事情

我希望是#3。有任何想法吗?

4

1 回答 1

3

谜团已揭开!这是Content-Length标题,或者更确切地说,缺少标题。@MaxDounin 的想法是正确的,只是我没有遵循它。

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

于 2012-10-04T23:20:41.947 回答