Abbiamo un servizio Web che serve piccoli segmenti arbitrari di un inventario fisso di file MP3 più grandi. I file MP3 sono generati al volo da un'applicazione python. Il modello è, fai una richiesta GET a un URL che specifica quali segmenti vuoi, ottieni uno stream audio/mpeg
in risposta. Questo è un processo costoso.Esiste un modo migliore per servire i risultati di un costoso processo Python bloccante su HTTP?
Stiamo utilizzando Nginx come gestore di richieste front-end. Nginx si occupa delle risposte alla cache per richieste comuni.
Inizialmente abbiamo provato a utilizzare Tornado sul back-end per gestire le richieste da Nginx. Come ci si aspetterebbe, l'operazione di blocco MP3 ha impedito a Tornado di fare la sua cosa (I/O asincrono). Quindi, siamo passati al multithreading, che ha risolto il problema del blocco e si sono comportati abbastanza bene. Tuttavia, ha introdotto una condizione di gara sottile (sotto carico del mondo reale) che non siamo ancora stati in grado di diagnosticare o riprodurre. Le condizioni della gara corrompono la nostra uscita MP3.
Così abbiamo deciso di impostare la nostra applicazione come un semplice gestore WSGI dietro Apache/mod_wsgi (sempre con Nginx in primo piano). Questo elimina il problema di blocco e la condizione di competizione, ma crea un carico a cascata (ad esempio Apache crea troppi processi) sul server in condizioni reali. Stiamo lavorando alla messa a punto di Apache/mod_wsgi in questo momento, ma ancora in fase di prova ed errori. (Aggiornamento: siamo tornati a Tornado. Vedi sotto.)
Infine, la domanda: ci manca qualcosa? Esiste un modo migliore per servire le risorse costose della CPU su HTTP?
Aggiornamento: Grazie all'articolo informato di Graham, sono abbastanza sicuro che si tratta di un problema di ottimizzazione di Apache. Nel frattempo, siamo tornati a utilizzare Tornado e stiamo cercando di risolvere il problema della corruzione dei dati.
Per coloro che sono stati così veloci da gettare più ferro sul problema, Tornado e un po 'di multi-threading (nonostante il problema dell'integrità dei dati introdotto dalla filettatura) gestisce il carico in modo accettabile su un'istanza Amazon EC2 di piccole dimensioni (single core) .
Eccellente articolo. Grazie. Questo potrebbe finire per fare il trucco. –
In effetti, accetterò questo collegamento come la risposta migliore, poiché il problema sembra essere un problema di ottimizzazione di Apache. –