2013-08-08 15 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.

Problemi correlati