2012-09-26 9 views
5

Ultimamente abbiamo riscontrato un ritardo molto strano ma molto consistente durante il POSTing dal lato client javascript al nostro server.Misterioso ~ 1min di ritardo nel POST HTTP tra il browser e Nginx

Ecco la nostra tecnologia stack, da davanti a dietro:

  1. JavaScript personalizzato codice client
  2. Backbone.js
  3. Custom Backbone.sync() implementation
  4. jQuery.ajax() (1.7.2)
  5. XmlHttpRequest
  6. Browser (verificato su Firefox e Chrome)
  7. Internet
  8. Nginx front-end
  9. Intranet (via Nginx http:// monte)
  10. Nginx back-end
  11. Gunicorn (via Nginx unix:// presa a monte)
  12. Django 1.4
  13. django-tastypie

(Nota a margine: non si fa mai un passo indietro in soggezione ? W complicato sviluppo web è)

Ecco una cronologia degli eventi:

  1. codice client chiama .save() su un backbone di nuova creazione APIModel.
  2. La nostra ordinazione .sync() si snoda verso client.send() che invia l'oggetto appena creato a $.ajax().
  3. I POST XmlHttpRequest risultanti. La richiesta viene visualizzata nel pannello Network dello strumento di sviluppo del browser, contrassegnato come in attesa di.
  4. La richiesta HTTP raggiunge Nginx, che la indirizza al backend django-tastypie.
  5. Tastypie gestisce la richiesta tempestivamente e in modo impeccabile, creando la risorsa e restituendo una risposta CREATA 201, con un'intestazione Location che punta alla nuova risorsa.
  6. Nginx registra la richiesta e (apparentemente) invia la risposta.
  7. Durata 1.1 minuti, durante il quale la richiesta è ancora contrassegnata come in attesa nel pannello Rete.
  8. La richiesta è contrassegnata come completa nel pannello Network del browser.
  9. I jQuery xhr gestori di incendi di successo
  10. di success handler rileva il codice e gli incendi 201 risposta fuori una successiva richiesta GET alla Posizione Il nostro client API personalizzata.
  11. Le solite cose accadono, il GET risponde prontamente e l'oggetto più esterno $.Deferred() si risolve, attivando qualsiasi gestore di successo del codice client associato.

Altri particolari da considerare:

  1. richieste GET e PUT richieste in una stessa determinazione pila prontamente.
  2. Quando si interagisce direttamente con Nginx più esterno tramite un client HTTP dedicato, le richieste POST identiche alla richiesta in questione vengono risolte immediatamente.
  3. La rimozione del gestore 201 del caso speciale e il successivo GET non hanno alcun effetto sul bug.
  4. Il ritardo è sempre 1,1 minuti. Ho usato console.time() per determinare che il ritardo varia all'interno della gamma di 65.000 ms.
  5. Il ritardo appare solo in questa configurazione. Non si verifica nelle nostre impostazioni di sviluppo, che sono leggermente più semplici.

presupposti non verificati sto facendo:

  1. volta Nginx registra una richiesta, la risposta è stato legato con un arco e inviati al cliente con una scritta a mano nota di ringraziamento.
  2. Questo non è un bug nei browser o in jQuery.

perdonare i minimi dettagli, ma ho fatto del mio meglio per eliminare le variabili, e allo stato attuale, mi sento sicuro nel dire che il problema è uno dei seguenti:

  1. un difetto nel la struttura fisica dell'universo
  2. un difetto nei modelli percettivi della nostra mente
  3. qualcos'altro non abbiamo ancora considerato

sono sperando in # 3. Qualche idea?

+0

_Quando interagisce direttamente con il server tramite un client HTTP dedicato, le richieste POST identiche alla richiesta in questione vengono risolte prontamente._ -> Quale server esattamente? – tomdemuyt

+0

Buona domanda. Il più estremo Nginx. Aggiornato gli altri dettagli per riflettere questo. –

+0

Sembra che ci sia una sorta di attivazione del watchdog di timeout, come se la risposta HTTP non venisse chiusa correttamente. – Pointy

risposta

3

Mistero risolto! Era l'intestazione Content-Length, o meglio, la mancanza di uno. @MaxDounin ha avuto l'idea giusta, non l'ho seguito abbastanza lontano.

Abilitare il Django django.middleware.http.ConditionalGetMiddleware ha fatto il trucco. (Questo middleware imposta l'intestazione Content-Length.)

+0

L'intestazione Content-Length mancante non è un motivo per un ritardo a meno che non vi sia un bug da qualche parte. Anche se potrebbe essere sufficiente impostare Content-Length per risolvere il problema, non è ancora noto quale sia il problema. –

+0

Stiamo eseguendo un Nginx abbastanza antico: 0.7.65-1ubuntu2 (Ubuntu Lucid). Forse avrei dovuto prenderne nota? –