Mysterious ~1min delay in HTTP POST between browser and Nginx

谁说胖子不能爱 提交于 2019-12-07 06:29:42

问题


We've lately been experiencing a very strange but very consistent delay when POSTing from client-side javascript to our server.

Here's our technology stack, from front to back:

  1. Custom javascript client code
  2. Backbone.js
  3. Custom Backbone.sync() implementation
  4. jQuery.ajax() (1.7.2)
  5. XmlHttpRequest
  6. Browser (verified on both Firefox and Chrome)
  7. Internet
  8. Nginx front-end
  9. Intranet (via Nginx http:// upstream)
  10. Nginx back-end
  11. Gunicorn (via Nginx unix:// upstream socket)
  12. Django 1.4
  13. django-tastypie

(Side note: do you ever just step back in awe at how complicated web development is?)

Here's a timeline of events:

  1. Client code calls .save() on a newly created Backbone APIModel.
  2. Our custom .sync() winds its way to client.send() which dispatches the newly created object to $.ajax().
  3. The resulting XmlHttpRequest POSTs. The request appears in the browser dev tool's Network pane, marked as pending.
  4. The HTTP request reaches Nginx, which routes it to the django-tastypie backend.
  5. Tastypie handles the request promptly and flawlessly, creating the resource, and returning a 201 CREATED response, with a Location header pointing to the new resource.
  6. Nginx logs the request and (ostensibly) sends the response.
  7. 1.1 minutes elapse, during which the request is still marked as pending in the Network pane.
  8. The request is marked as complete in the browser's Network pane.
  9. The jQuery xhr fires success handlers
  10. Our custom API client's success handler detects the 201 response code and fires off a subsequent GET request to the Location.
  11. The usual stuff happens, the GET responds promptly, and the outermost $.Deferred() object resolves, firing any associated client code success handlers.

Other details to consider:

  1. GET requests and PUT requests in the same stack resolve promptly.
  2. When interacting directly with the outermost Nginx via a dedicated HTTP client, POST requests identical to the request in question resolve promptly.
  3. Removing the special-case 201 handler and subsequent GET has no effect on the bug.
  4. The delay is always 1.1 minutes. I've used console.time() to determine that the delay varies within the 65,000ms range.
  5. The delay only appears in this configuration. It does not occur in our development setups, which are slightly simpler.

Unverified assumptions I'm making:

  1. Once Nginx logs a request, the response has been tied up with a bow and sent to the client with a handwritten thank-you note.
  2. This is not a bug in the browsers or in jQuery.

Forgive the painstaking detail, but I've done my best to eliminate variables, and at present, I feel safe in saying that the problem is one of the following:

  1. a flaw in the physical structure of the universe
  2. a flaw in the perceptual models of our minds
  3. something else we haven't considered yet

I'm hoping for #3. Any ideas?


回答1:


Mystery solved! It was the Content-Length header, or rather, the lack of one. @MaxDounin had the right idea, I just didn't follow it far enough.

Enabling Django's django.middleware.http.ConditionalGetMiddleware did the trick. (This middleware sets the Content-Length header.)



来源:https://stackoverflow.com/questions/12606898/mysterious-1min-delay-in-http-post-between-browser-and-nginx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!