2013-08-08 11 views
7

Ho un'applicazione Rails (v3.2.13, Ruby 2.0.0) in esecuzione su nginx + Unicorn (Ubuntu 12.04). Tutto funziona bene, tranne quando un utente amministratore sta caricando utenti (migliaia) tramite un file CVS. Il problema è che ho impostato il timeout a 30 secondi e il processo di importazione richiede molto più tempo. Quindi, dopo 30 secondi ricevo una pagina di Bad Gateway nginx 502 (l'operatore Unicorn viene ucciso).Come configurare nginx + Unicorn per evitare errori di timeout?

La soluzione ovvia è aumentare il timeout, ma non lo voglio perché causerà un altro problema (credo), perché non è un comportamento tipico.

C'è un modo per gestire questo tipo di problemi?

Grazie mille in anticipo.

PS: Forse una soluzione è modificare il codice. In tal caso, voglio evitare all'utente di eseguire un'altra richiesta.

Alcune idee (non so se è possibile):

  • impostare un lavoratore dedicato a questa richiesta.
  • Invia un segnale "work in progress" a Unicorn per evitare di essere ucciso.

nginx-app.conf

upstream xxx { 
    server unix:/tmp/xxx.socket fail_timeout=0; 
} 


server { 
    listen 80; 

    ... 

    location/{ 

    proxy_pass http://xxx; 
    proxy_redirect  off; 
    ... 

    proxy_connect_timeout  360; 
    proxy_send_timeout   360; 
    proxy_read_timeout   360; 
    } 
} 

unicorn.rb

worker_processes 2 

listen "/tmp/xxx.socket" 

timeout 30 

pid "/tmp/unicorn.xxx.pid" 
+0

PS troppo corto, si prega di allungarlo. – juanpastas

+0

Grazie @juanpastas, molto utile. – cortex

+2

Solo una nota. I valori di 'proxy_connect_timeout',' proxy_send_timeout', 'proxy_read_timeout' sono anormali. Per favore, leggi la documentazione, probabilmente non capisci il loro significato. E 'fail_timeout = 0' è assolutamente privo di significato. – VBart

risposta

9

Questa è una buona ragione per creare una coda. E si vuole:

  • file di caricamento CSV (che dovrebbe essere entro 30sec)
  • vostro processo in background che consente di importare i dati dell'utente (che può andare per ore ...)
  • mentre questo lavoro è in corso voi può servire un qualche tipo di pagina WIP con stato del lavoro/percentuali/ecc.

Controllare https://github.com/resque/resque ad esempio. Ci sono molte altre code.

+0

In questo modo puoi fare un sacco di cose ... come mandare migliaia di email, convertire video/immagini ... Tante cose. – NilColor

+0

Resque è essenzialmente la stessa cosa di Ruby Thread? O sono via? http: //www.ruby-doc.org/core-2.1.1/Thread.html –

+0

No. Questa è Message Queue (http://en.wikipedia.org/wiki/Message_queue). Resque stesso usa i thread, certo. La discussione è per l'elaborazione parallela. Coda per l'elaborazione asincrona. – NilColor

2

Esiste un modo per gestire questo tipo di problemi?

Fare il lavoro in background. Dovresti avere un processo separato che recuperi i lavori dalla coda uno alla volta e li elabori. E poiché non funziona con le richieste degli utenti, può fare il suo lavoro per tutto il tempo necessario. Non hai bisogno di unicorno per questo, solo un demone separato.