Re: [Python] Deploy con nginx e proxy_pass - epilogo
On Sat, Jan 04, 2014 at 12:21:30PM +0100, Manlio Perillo wrote: > On 03/01/2014 12:50, Roberto De Ioris wrote: > >[...] > >provate a ridurre a 3 secondi il proxy_connect_timeout di nginx, > > Dato che Linux ignora l'hint sulla backlog, il parametro su cui agire è > proxy_send_timeout. > > Sul wiki di Nginx c'è un commento appropriato riguardo > proxy_connect_timeout: > http://wiki.nginx.org/HttpProxyModule#proxy_connect_timeout > http://wiki.nginx.org/HttpProxyModule#proxy_read_timeout > > Impostare proxy_send_timeout potrebbe non essere efficace, a causa > del buffering effettuato dal kernel. In questo caso occorre > modificare proxy_read_timeout, ma va fatto con cautela per evitare > di mandare in timeout richieste legittime (ma semplicemente lente). > In alternativa si può provare a modificare, dall'applicazione > Python, SO_RCVBUF. Purtroppo anche la modifica del send_timeout non ha sortito alcun effetto. Non ho provato a modifcare SO_RCVBUF. Ho alla fine preso una strada completamente differente che però in concreto ha dati i risultati desiderati. Ho deciso di creare 2 pool di processi (upstream) differenti uno per i processi lenti ed uno per gli altri. Dal momento che le chiamate lente hanno URL ben definiti, ho deciso di redirigere queste chiamate su un pool di processi differente. In questo modo so per certo che una chiamata veloce non sarà mai rallentata da una lenta e, semplicemnete aumentando i processi lenti posso arrivare a sincerarmi che nessun processo lento abbia una probabilità significativa di trovarsi in coda ad un altro processo lento (da momento che sono relativamente pochi al giorno). Ora possiamo dedicarci a capire cosa hanno di sbagliato i processi lenti... Grazie a Manlio e Roberto per l'aiuto offerto sandro -- Sandro Dentella *:-) http://www.reteisi.org Soluzioni libere per le scuole http://sqlkit.argolinux.orgSQLkit home page - PyGTK/python/sqlalchemy ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
On 03/01/2014 12:50, Roberto De Ioris wrote: [...] provate a ridurre a 3 secondi il proxy_connect_timeout di nginx, Dato che Linux ignora l'hint sulla backlog, il parametro su cui agire è proxy_send_timeout. Sul wiki di Nginx c'è un commento appropriato riguardo proxy_connect_timeout: http://wiki.nginx.org/HttpProxyModule#proxy_connect_timeout http://wiki.nginx.org/HttpProxyModule#proxy_read_timeout Impostare proxy_send_timeout potrebbe non essere efficace, a causa del buffering effettuato dal kernel. In questo caso occorre modificare proxy_read_timeout, ma va fatto con cautela per evitare di mandare in timeout richieste legittime (ma semplicemente lente). In alternativa si può provare a modificare, dall'applicazione Python, SO_RCVBUF. > [...] Ciao Manlio ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
On 03/01/2014 18:42, Alessandro Dentella wrote: On Fri, Jan 03, 2014 at 12:45:02PM +0100, Manlio Perillo wrote: On 03/01/2014 12:34, Alessandro Dentella wrote: [...] La nostra simulazione è stata fatta con 2 funzioni: is_up e blocking che usa time.sleep() class IsUp(tornado.web.RequestHandler): def get(self): self.write("Is Up Porta %d" ...) self.finish() class Blocking(tornado.web.RequestHandler): def get(self, numero=10): time.sleep(int(numero)) self.write("Bloccato Porta %s\n" % options.port) self.finish() la chiamata usando 'wget -q -O - http://ngtest/blocking/30/' ed interrompendolo con Control-c. Ok. Ma quante instanze di tornado hai attive? 10 al momento, vedi descrizione qui [1] Allora, vediamo se ho capito. Hai scritto che: > la chiamata usando 'wget -q -O - http://ngtest/blocking/30/' ed > interrompendolo con Control-c. > In un terminale separato in ciclo di >'wget -q -O - http://ngtest/is_up' > Il ciclo si blocca nel momento della interruzione e riprende solo > quando termita il tempo (e quindi il processo si libera) Quindi quello che fai è prima richiedere http://ngtest/blocking/30/, in modo che una delle instanze di tornado si blocchi per 30 secondi, e poi un serie di richieste normali per vedere se le altre instanze rispondono. Quello che succede è che in condizioni normali, ottieni subito una risposta instantanea, ma non appena termini in modo brusco la prima richiesta, Nginx considera quella instanza libera e quindi una delle richieste normali blocca. Secondo me il problema è quello che ti ha indicato Roberto. La tua instanza di tornado è bloccata dalla sleep, ma continua ad accettare connessioni a causa della backlog nella listen. Vedi: http://stackoverflow.com/questions/5111040/listen-ignores-the-backlog-argument Se usi Linux quindi direi che hai un bel problema. [...] Come già detto in altra mail, il problema residuo sorge quando una chiamata viene interrotta. Nginx libera subito la risorsa e passa una nuova chiamata a quel processo che in realtà è ancora occupato. E' occupato, ma continua ad accettare connessioni da parte di Nginx. Mi vengono in mente un paio di soluzioni brusche, ma dipende da come gestisci questa situazione nel caso "reale". Nel test che hai fatto, interrompevi la connessione manualmente. Nel caso reale cosa succede? Da quello che scrivi mi sembra di capire che la connessione venga interrotta bruscamente. Ma in che modo? Ad esempio, per "risolvere" il problema, puoi terminare e poi riavviare il processo nel caso in cui una connessione con Nginx viene interrotta prima che la richiesta HTTP termini normalmente. Non so se è possibile nel tuo caso, dovrei fare dei test. Ciao Manlio ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
On 03/01/2014 18:43, Roberto De Ioris wrote: [...] Io su soluzioni come gevent o microthread ho sempre questi due dubbi: 1) Usano il modello sincrono, "nascondendo" le azioni asincrone. Questo per molti è un vantaggio, ma a me non piacciono i pattern che ti nascondono le cose (specialmente se importanti). Inoltre, in linguaggi come go, non hai nessun controllo sul runtime e quindi non puoi ottimizzare l'esecuzione delle goroutine in eventuali casi particolari. ti do ragione (soprattutto su go, perche' un linguaggio venduto come 'linguaggio di sistema' mi deve permettere di fare porcherie :P). Quindi tu preferisci al: def mio_magico_thread(Greenlet): connect(address) send blah blah un (linguaggio inventato): fd = async_connect(address) wait_for_write(fd) suspend() # sono qui solo quando fd e' pronto if fd.ready(): send blah blah Quello che preferisco io è un linguaggio che mi permetta di creare i singoli blocchi, come voglio io e nel modo più efficiente che voglio. Inoltre voglio librerie che implementano i vari protocolli di rete a basso livello, e nel modo più efficiente possibile (quindi macchina a stato) e che facciano solo quello e bene. Come ho scritto, il mio esempio di riferimento è la libpq (solo che io sono più radicale e toglierei, se possibile, tutto l'I/O usando solo buffer che l'utente deve riempire/svuotare). 2) Efficienza. Che succede se in un processo Python con gevent stai gestendo un migliaio di threads? Quanta memoria stai usando? Soluzioni come gevent, goroutine e soci tendono ad usare moltissima memoria virtuale, che potrebbe facilmente risultare in una degradazione delle performance, a causa dello swapping. beh la swap la puoi disabilitare, comunque le greenlet consumano un bel po' di memoria (meno di un thread python comunque) ma su un sistema con 32G di ram ce ne fai girare almeno 200k quindi piu' che sufficiente a gestire le connessioni che puoi fare su un singolo ip. Io sono di parte, perchè il mio vecchio laptop ha 2GB di memoria, e mi da fastidio quando vedo software che usano la memoria in modo allegro. Con gevent non e' la ram il problema, e' che e' poco efficiente nella parte syscall in quanto per facilitare la vita allo sviluppatore, cancella e ri-registra i file descriptor ad ogni giro. Dopo qualche migliaio di greenlet in funzione il carico di sistema schizza di brutto. Facilitare la vita al programmatore "casuale" ed efficienza non sembra vadano molto d'accordo. C'e' poi da dire che gestire tali moli di concorrenza richiede un tuning di tutta la macchina e (soprattutto) dei servizi come i database che devono essere pronti a gestire centiaia di query in blocco. Sicuramente. Aggiungerei che c'è anche bisogno di un tuning del cervello dei programmatori che si trovano a sviluppare software di questo tipo ;). Ciao Manlio ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
2014/1/3 Manlio Perillo > > No, direi che è banale. > Usi Apache + mod_wsgi e spendi tanti bei soldi in hardware :) Ok. Quindi non riesci a farlo scalare. > > Vedi il fatto che su Windows hai solo l'equivalente di posix_aio ma non > quello di epoll/kqueue. Potrei continuare all'infinito... > Parliamo poi del fatto che anche solo avere epoll e non kqueue e' una discreta rottura di palle... > > L'altra mancanza grave è l'implementazione dei "protocolli" di > comunicazione. Nella libreria standard di Python (ma non solo) hai > praticamente dei *giocattoli*. Le implementazioni serie sono nei framework > asincroni, ed **ognuno** reimplementa tutto e funziona solo con quel > framework. La libreria standard di Python reinventerà tutto di nuovo, > perchè avrà il suo bel framework asincrono, su cui poi si dovranno > reimplementare tutti i protocolli. > Gia'. Ovviamente per motivi politici sarebbe stato un casino sceglierne uno. In realta' non mi dispiace nemmeno, a patto che sia veramente una "lesson learned" che partano da 0. Ovviamente se riescono a prendere il meglio di quello che c'e' e lasciare fuori le cazzate. Oh, alla fine dei conti, nei primi anni 90, quando Python nasceva, non si pensava ai framework asincroni. > L'API migliore che ho visto è quella della libpq, per la cronaca. > Migliore perchè non dipende da nessun framework, e si mantiene usabile. > ah... gia'. Ma anche il buon vecchio zero non e' che scherza... Specie la nuova re-implementazione, promette meraviglie. >E' vero che ci sono dei monkey patch per alcune funzioni della >> libreria standard, ma non ritengo sia saggio affidarsi ciecamente a >> loro. >> >> >> Funzionicchiano, via. Parlo di gevent, non so quelli di tornado. >> >> > Visto che Tornado usa gevent, immagino si basi su quelli. Gia', ma non so se aggiunge altro che complica il tutto. Python e la libreria standard semplicemente non sono pensati per >> un ambiente a green thread. >> >> Ma no, se hai un martello sufficientemente grande (e non hai paura di >> usarlo) si fa tutto. ;) >> > > Incluso scassare tutto alla prima disattenzione. ;) Chiaro. Fa parte del gioco... -- . ..: -enrico- ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
On Fri, Jan 03, 2014 at 12:50:54PM +0100, Roberto De Ioris wrote: > > > On Mon, Dec 30, 2013 at 05:26:57PM +0100, Roberto De Ioris wrote: > >> > Mi pare di capire che la soluzione della listen queue che mi hai > >> indicato > >> > risolverebbe questo problema. > >> > > >> > >> > >> server = HTTPServer(app) > >> server.bind(post, backlog=1) > >> > >> (prova anche con zero, su alcuni kernel funziona, anche se non ricordo > >> se > >> e' per quelli piu' recenti o quelli piu' vecchi) > > > > Purtroppo questa strada non ha funzionato. Ricordo che il probelma che > > cerchiamo di risolvere è che quando viene interrotto una chiamata "lunga", > > nginx libera quella connessione e quindi diritta verso quel processo la > > prossima chiamata, ma il processo di fatto è occupato. > > > > La nostra simulazione è stata fatta con 2 funzioni: is_up e blocking che > > usa > > time.sleep() > > > >class IsUp(tornado.web.RequestHandler): > >def get(self): > >self.write("Is Up Porta %d" ...) > > self.finish() > > > >class Blocking(tornado.web.RequestHandler): > >def get(self, numero=10): > >time.sleep(int(numero)) > > self.write("Bloccato Porta %s\n" % options.port) > > self.finish() > > > > la chiamata usando 'wget -q -O - http://ngtest/blocking/30/' ed > > interrompendolo con Control-c. > > In un terminale separato in ciclo di 'wget -q -O - http://ngtest/is_up' > > Il ciclo si blocca nel momento della interruzione e riprende solo quando > > termita il tempo (e quindi il processo si libera) > > Provate a ridurre a 3 secondi il proxy_connect_timeout di nginx, e' > probabile che abbiate sempre almeno uno slot listen_queue libero anche se > lo avete impostato a 1/0. In questo modo se la connessione non completa in > 3 secondi, nginx considera il peer morto (e passa a quello dopo se lo > avete configurato a dovere) nessun cambiamento. Il proxy_connect_timeout pare proprio ignorato. questa la conf: server { listen 80; server_name ngtest; location / { proxy_pass_header Server; proxy_set_header Host $http_host; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Scheme $scheme; proxy_connect_timeout 3s; proxy_pass http://produzione; } } > > Credo di capire che vengono descritte più opzioni di configurazione: con i > > greenlet ed una programmazione asincrona o con processi tornado > > indipendenti. > > guarda terrei questo approccio proprio come ultima spiaggia (e > probabilmente e' piu' semplice modificare tornado) se la soluzione sopra > non dovesse funzionare ecco appunto... Il primo punto: capisco correttamente che la conf è quella descritta nel capitoletto "Binding and listening with Tornado"? Nella mail precedente scrivevi: > L'approccio migliore (o meglio diciamo quello risolutivo) e' che i > processi usino lo stesso socket, puoi provare il plugin tornado di uWSGI: ora la dici "ultima spiaggia". come mai? sandro *:-) ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
> On 03/01/2014 18:09, Roberto De Ioris wrote: >> [...] >> >> Python e' utilizzabilissimo, e' solo che devi essere "consapevole" >> (stessa >> cosa in ruby o in perl), poiche' ci sono diversi framework per la >> programmazione asincrona e devi sceglierne uno (io consiglio sempre >> gevent, ma dopo averlo studiato, non perche' sia migliore tecnicamente >> ma >> perche' e' quello con la base di utilizzatori e librerie piu' ampia e >> mantenuta di questi tempi [e poi io do' sempre valore aggiunto ai >> progetti >> in cui il core developer non e' un "asshole"]). >> >> la differenza con node, erlang, go (e rust e tanti altri) e' che il >> framework asincrono e' direttamente parte del core cosi' come le >> primitive >> per i microthread. L'utente non deve preoccuparsi (piu' o meno) che >> qualche operazione sia bloccante. >> > > Io su soluzioni come gevent o microthread ho sempre questi due dubbi: > > 1) Usano il modello sincrono, "nascondendo" le azioni asincrone. > Questo per molti è un vantaggio, ma a me non piacciono i pattern che > ti nascondono le cose (specialmente se importanti). > Inoltre, in linguaggi come go, non hai nessun controllo sul runtime > e quindi non puoi ottimizzare l'esecuzione delle goroutine in > eventuali casi particolari. ti do ragione (soprattutto su go, perche' un linguaggio venduto come 'linguaggio di sistema' mi deve permettere di fare porcherie :P). Quindi tu preferisci al: def mio_magico_thread(Greenlet): connect(address) send blah blah un (linguaggio inventato): fd = async_connect(address) wait_for_write(fd) suspend() # sono qui solo quando fd e' pronto if fd.ready(): send blah blah > > 2) Efficienza. > Che succede se in un processo Python con gevent stai gestendo un > migliaio di threads? Quanta memoria stai usando? > > Soluzioni come gevent, goroutine e soci tendono ad usare moltissima > memoria virtuale, che potrebbe facilmente risultare in una > degradazione delle performance, a causa dello swapping. beh la swap la puoi disabilitare, comunque le greenlet consumano un bel po' di memoria (meno di un thread python comunque) ma su un sistema con 32G di ram ce ne fai girare almeno 200k quindi piu' che sufficiente a gestire le connessioni che puoi fare su un singolo ip. Con gevent non e' la ram il problema, e' che e' poco efficiente nella parte syscall in quanto per facilitare la vita allo sviluppatore, cancella e ri-registra i file descriptor ad ogni giro. Dopo qualche migliaio di greenlet in funzione il carico di sistema schizza di brutto. C'e' poi da dire che gestire tali moli di concorrenza richiede un tuning di tutta la macchina e (soprattutto) dei servizi come i database che devono essere pronti a gestire centiaia di query in blocco. -- Roberto De Ioris http://unbit.it ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
On Fri, Jan 03, 2014 at 12:45:02PM +0100, Manlio Perillo wrote: > On 03/01/2014 12:34, Alessandro Dentella wrote: > >[...] > >La nostra simulazione è stata fatta con 2 funzioni: is_up e blocking che usa > >time.sleep() > > > >class IsUp(tornado.web.RequestHandler): > >def get(self): > >self.write("Is Up Porta %d" ...) > > self.finish() > > > >class Blocking(tornado.web.RequestHandler): > >def get(self, numero=10): > >time.sleep(int(numero)) > > self.write("Bloccato Porta %s\n" % options.port) > > self.finish() > > > >la chiamata usando 'wget -q -O - http://ngtest/blocking/30/' ed > >interrompendolo con Control-c. > > Ok. > Ma quante instanze di tornado hai attive? 10 al momento, vedi descrizione qui [1] > Se ne hai attiva una sola, mi sembra ovvio che blocca tutto. > > Se ne hai N, facendo N richieste di questo genere blocchi ancora tutto. Certo ma ho poche richieste bloccanti (2% > 2 secondi) ed un totale molto basso di richieste lente: 100/giorno > 10 secondi, 300/giorno> 4 secondi. > >In un terminale separato in ciclo di 'wget -q -O - http://ngtest/is_up' > >Il ciclo si blocca nel momento della interruzione e riprende solo quando > >termita il tempo (e quindi il processo si libera) > > > > Che ciclo? un for della bash > Per concludere, tieni conto che usare cose come Tornado è tutt'altro > che banale. Tutto lo stack (applicazione + framework + eventuali > librerie) deve essere sviluppato con la programmazione asincrona in > mente. E' vero che ci sono dei monkey patch per alcune funzioni > della libreria standard, ma non ritengo sia saggio affidarsi > ciecamente a loro. Python e la libreria standard semplicemente non > sono pensati per un ambiente a green thread. Questo è il peccato originale che non dipende da me all'interno del quale mi devo muovere. Chi ha scritto l'applicazione non ha capito la specificità di tornado ed ha fatto una programmazione basata su richieste non asincone. In questo quadro e per il poco tempo che io mi occupo di questo progetto ho solo potuto suggerire nell'ordine 1) di passare a django 2) di modificare il setup per moltiplicare i processi in modo da evitare i blocchi 3) di ottimizzare alcune funzioni che probabilmente prendono tempo quando non dovrebbero. Come già detto in altra mail, il problema residuo sorge quando una chiamata viene interrotta. Nginx libera subito la risorsa e passa una nuova chiamata a quel processo che in realtà è ancora occupato. sandro [1] http://comments.gmane.org/gmane.comp.python.general.italian/14562 ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
On 03/01/2014 18:09, Roberto De Ioris wrote: [...] Python e' utilizzabilissimo, e' solo che devi essere "consapevole" (stessa cosa in ruby o in perl), poiche' ci sono diversi framework per la programmazione asincrona e devi sceglierne uno (io consiglio sempre gevent, ma dopo averlo studiato, non perche' sia migliore tecnicamente ma perche' e' quello con la base di utilizzatori e librerie piu' ampia e mantenuta di questi tempi [e poi io do' sempre valore aggiunto ai progetti in cui il core developer non e' un "asshole"]). la differenza con node, erlang, go (e rust e tanti altri) e' che il framework asincrono e' direttamente parte del core cosi' come le primitive per i microthread. L'utente non deve preoccuparsi (piu' o meno) che qualche operazione sia bloccante. Io su soluzioni come gevent o microthread ho sempre questi due dubbi: 1) Usano il modello sincrono, "nascondendo" le azioni asincrone. Questo per molti è un vantaggio, ma a me non piacciono i pattern che ti nascondono le cose (specialmente se importanti). Inoltre, in linguaggi come go, non hai nessun controllo sul runtime e quindi non puoi ottimizzare l'esecuzione delle goroutine in eventuali casi particolari. 2) Efficienza. Che succede se in un processo Python con gevent stai gestendo un migliaio di threads? Quanta memoria stai usando? Soluzioni come gevent, goroutine e soci tendono ad usare moltissima memoria virtuale, che potrebbe facilmente risultare in una degradazione delle performance, a causa dello swapping. > [...] Ciao Manlio ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
> 2014/1/3 enrico franchi > >> >> 2014/1/3 Manlio Perillo >> >>> Per concludere, tieni conto che usare cose come Tornado è tutt'altro >>> che >>> banale. >>> >> >> Beh, fare scalare qualcosa di non asincrono e' ancora meno banale, IMHO. >> >> >>> Tutto lo stack (applicazione + framework + eventuali librerie) deve >>> essere sviluppato con la programmazione asincrona in mente. >>> >> >> Vero. Ma d'altra parte non e' che ci sia un mucchio di soluzioni. O >> molli >> python del tutto... >> >> > > A parte erlang e nodejs c'è altro di utilizzabile?go? Python e' utilizzabilissimo, e' solo che devi essere "consapevole" (stessa cosa in ruby o in perl), poiche' ci sono diversi framework per la programmazione asincrona e devi sceglierne uno (io consiglio sempre gevent, ma dopo averlo studiato, non perche' sia migliore tecnicamente ma perche' e' quello con la base di utilizzatori e librerie piu' ampia e mantenuta di questi tempi [e poi io do' sempre valore aggiunto ai progetti in cui il core developer non e' un "asshole"]). la differenza con node, erlang, go (e rust e tanti altri) e' che il framework asincrono e' direttamente parte del core cosi' come le primitive per i microthread. L'utente non deve preoccuparsi (piu' o meno) che qualche operazione sia bloccante. NOTA personale perche' oggi mi sento polemico: passare da python ad erlang non significa cambiare linguaggio, significa cambiare totalmente l'approccio allo sviluppo, io ho serie difficolta' a credere che questi tipi di transizioni siano rapide come molti millantano, soprattutto in ambiente lavorativo. -- Roberto De Ioris http://unbit.it ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
2014/1/3 enrico franchi > > 2014/1/3 Manlio Perillo > >> Per concludere, tieni conto che usare cose come Tornado è tutt'altro che >> banale. >> > > Beh, fare scalare qualcosa di non asincrono e' ancora meno banale, IMHO. > > >> Tutto lo stack (applicazione + framework + eventuali librerie) deve >> essere sviluppato con la programmazione asincrona in mente. >> > > Vero. Ma d'altra parte non e' che ci sia un mucchio di soluzioni. O molli > python del tutto... > > A parte erlang e nodejs c'è altro di utilizzabile?go? > E' vero che ci sono dei monkey patch per alcune funzioni della libreria >> standard, ma non ritengo sia saggio affidarsi ciecamente a loro. >> > > Funzionicchiano, via. Parlo di gevent, non so quelli di tornado. > > >> Python e la libreria standard semplicemente non sono pensati per un >> ambiente a green thread. >> > > Ma no, se hai un martello sufficientemente grande (e non hai paura di > usarlo) si fa tutto. ;) > Si, vero che non sono pensati, quello e' indubbio. Pero' diciamo che ce la > si fa… ;) > > -ho visto perfino django martellato a forza in logiche asincrone (backend, > non frontend) - > > > -- > . > ..: -enrico- > > ___ > Python mailing list > Python@lists.python.it > http://lists.python.it/mailman/listinfo/python > > ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
On 03/01/2014 16:41, enrico franchi wrote: 2014/1/3 Manlio Perillo mailto:manlio.peri...@gmail.com>> Per concludere, tieni conto che usare cose come Tornado è tutt'altro che banale. Beh, fare scalare qualcosa di non asincrono e' ancora meno banale, IMHO. No, direi che è banale. Usi Apache + mod_wsgi e spendi tanti bei soldi in hardware :) Tutto lo stack (applicazione + framework + eventuali librerie) deve essere sviluppato con la programmazione asincrona in mente. Vero. Ma d'altra parte non e' che ci sia un mucchio di soluzioni. O molli python del tutto... Le soluzioni ci sarebbero pure. A livello di sistema operativo il supporto c'è. Il problema è che non è uniforme come dovrebbe. Vedi ad esempio le differenze nell'implementazione di posix_aio, il fatto che posix_aio funziona solo sui file ma nulla vieta in teoria di usarlo anche per i socket e altro. Vedi il fatto che USB che è asincrono per natura, nelle varie implementazioni non usa l'interfaccia posix_aio, ma una diversa (parlo di USB perchè lo devo usare per un progetto personale e mi sto sentendo male a vedere come è implementato). Vedi il fatto che su Windows hai solo l'equivalente di posix_aio ma non quello di epoll/kqueue. Potrei continuare all'infinito... L'altra mancanza grave è l'implementazione dei "protocolli" di comunicazione. Nella libreria standard di Python (ma non solo) hai praticamente dei *giocattoli*. Le implementazioni serie sono nei framework asincroni, ed **ognuno** reimplementa tutto e funziona solo con quel framework. La libreria standard di Python reinventerà tutto di nuovo, perchè avrà il suo bel framework asincrono, su cui poi si dovranno reimplementare tutti i protocolli. L'API migliore che ho visto è quella della libpq, per la cronaca. Migliore perchè non dipende da nessun framework, e si mantiene usabile. [[piccolo rant di inizio anno]] E' vero che ci sono dei monkey patch per alcune funzioni della libreria standard, ma non ritengo sia saggio affidarsi ciecamente a loro. Funzionicchiano, via. Parlo di gevent, non so quelli di tornado. Visto che Tornado usa gevent, immagino si basi su quelli. Python e la libreria standard semplicemente non sono pensati per un ambiente a green thread. Ma no, se hai un martello sufficientemente grande (e non hai paura di usarlo) si fa tutto. ;) Incluso scassare tutto alla prima disattenzione. ;) Si, vero che non sono pensati, quello e' indubbio. Pero' diciamo che ce la si fa… ;) -ho visto perfino django martellato a forza in logiche asincrone (backend, non frontend) - Ciao Manlio ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
Ok, grazie, stupido io non avevo fatto caso alle versioni. Ora provo a pastrocchiare un po' mentre aspetto Alessandro :) Luca Il giorno 03 gennaio 2014 15:09, Roberto De Ioris ha scritto: > > > nono, ho controllato > > > > (wall)root@wadev:/dati/wall# python -c"import greenlet;print > > greenlet.__version__" > > 0.4.1 > > > > Mi ero perso il pezzo in cui dicevi di aver istallato greenlet dai > pacchetti di ubuntu. > > Devi usare la stessa versione di greenlet nel venv usata per compilare > uWSGI, probabilmente ti conviene compilare uwsgi direttamente dal venv > cosi' eviti di dover disistallare i package di ubuntu (o sovrascriverli) > > > -- > Roberto De Ioris > http://unbit.it > ___ > Python mailing list > Python@lists.python.it > http://lists.python.it/mailman/listinfo/python > ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
2014/1/3 Manlio Perillo > Per concludere, tieni conto che usare cose come Tornado è tutt'altro che > banale. > Beh, fare scalare qualcosa di non asincrono e' ancora meno banale, IMHO. > Tutto lo stack (applicazione + framework + eventuali librerie) deve essere > sviluppato con la programmazione asincrona in mente. > Vero. Ma d'altra parte non e' che ci sia un mucchio di soluzioni. O molli python del tutto... > E' vero che ci sono dei monkey patch per alcune funzioni della libreria > standard, ma non ritengo sia saggio affidarsi ciecamente a loro. > Funzionicchiano, via. Parlo di gevent, non so quelli di tornado. > Python e la libreria standard semplicemente non sono pensati per un > ambiente a green thread. > Ma no, se hai un martello sufficientemente grande (e non hai paura di usarlo) si fa tutto. ;) Si, vero che non sono pensati, quello e' indubbio. Pero' diciamo che ce la si fa… ;) -ho visto perfino django martellato a forza in logiche asincrone (backend, non frontend) - -- . ..: -enrico- ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
> nono, ho controllato > > (wall)root@wadev:/dati/wall# python -c"import greenlet;print > greenlet.__version__" > 0.4.1 > Mi ero perso il pezzo in cui dicevi di aver istallato greenlet dai pacchetti di ubuntu. Devi usare la stessa versione di greenlet nel venv usata per compilare uWSGI, probabilmente ti conviene compilare uwsgi direttamente dal venv cosi' eviti di dover disistallare i package di ubuntu (o sovrascriverli) -- Roberto De Ioris http://unbit.it ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
nono, ho controllato (wall)root@wadev:/dati/wall# python -c"import greenlet;print greenlet.__version__" 0.4.1 2014/1/3 Roberto De Ioris > > > Ok, come diceva Alessandro in realtà non siamo nemmeno riusciti a fare > > dei test con uWSGI e il plugin perchè da errori di Segmentation Fault > > usando --tornado 100 e --greenlet. Ma usando solo --tornado 100 da > > questo errore: > > *** DANGER *** tornado mode without coroutine/greenthread engine loaded > > !!! > > > > Installato e abilitato con: > > > > UWSGI_EMBED_PLUGINS=tornado,greenlet pip install greenlet uwsgi > > > > Dopo aver installato i pacchetti python-greenlet e python-greenlet-dev > > visto che senza diceva di non trovare greenlet/greenlet.h > > > > Qui sotto mette le informazioni che penso siano utili. > > > > > > # uname -a > > > > Linux wadev 3.2.0-57-generic #87-Ubuntu SMP Tue Nov 12 21:35:10 UTC 2013 > > x86_64 x86_64 x86_64 GNU/Linux > > - > > > > > > # uwsgi.ini > > > > [uwsgi] > > socket = 127.0.0.1:9090 > > uid = service > > gid = service > > pythonpath = /usr/local/python/Lib > > virtualenv = /dati/wall > > chdir = /dati/wall/src/test > > wsgi-file = uwsgi_test.py > > processes = 4 > > threads = 2 > > stats = 127.0.0.1:9191 > > tornado = 100 > > greenlet = > > > > ## Da risposta trovata in rete a proposito di Segmentation Fault. > > ;master = true > > ;enable-threads = true > > ;singe-interpreter = true > > > > > > # backtrace > > > > [uWSGI] getting INI configuration from uwsgi.ini > > *** Starting uWSGI 2.0 (64bit) on [Fri Jan 3 13:07:47 2014] *** > > compiled with version: 4.6.3 on 03 January 2014 09:42:28 > > os: Linux-3.2.0-57-generic #87-Ubuntu SMP Tue Nov 12 21:35:10 UTC 2013 > > nodename: wadev > > machine: x86_64 > > clock source: unix > > pcre jit disabled > > detected number of CPU cores: 2 > > current working directory: /usr/wall/wall > > detected binary path: /usr/wall/wall/bin/uwsgi > > setgid() to 1005 > > set additional group 27 (sudo) > > setuid() to 1005 > > your processes number limit is 15866 > > your memory page size is 4096 bytes > > detected max file descriptor number: 1024 > > - async cores set to 100 - fd table size: 1024 > > lock engine: pthread robust mutexes > > thunder lock: disabled (you can enable it with --thunder-lock) > > uwsgi socket 0 bound to TCP address 127.0.0.1:9090 fd 3 > > Python version: 2.7.3 (default, Sep 26 2013, 20:13:52) [GCC 4.6.3] > > Set PythonHome to /dati/wall > > Python main interpreter initialized at 0xa28aa0 > > python threads support enabled > > your server socket listen backlog is limited to 100 connections > > your mercy for graceful operations on workers is 60 seconds > > mapped 415280 bytes (405 KB) for 8 cores > > *** Operational MODE: preforking+threaded *** > > added /usr/local/python/Lib/ to pythonpath. > > WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0xa28aa0 > pid: > > 27566 (default app) > > !!! uWSGI process 27566 got Segmentation Fault !!! > > *** backtrace of 27566 *** > > uwsgi(uwsgi_backtrace+0x29) [0x467b69] > > uwsgi(uwsgi_segfault+0x21) [0x467cf1] > > /lib/x86_64-linux-gnu/libc.so.6(+0x364a0) [0x7fa4c9f8b4a0] > > uwsgi() [0x4a6494] > > uwsgi(uwsgi_init_all_apps+0xcf) [0x46897f] > > uwsgi(uwsgi_start+0xe6a) [0x4699fa] > > uwsgi(uwsgi_setup+0x1885) [0x46b955] > > uwsgi(main+0x9) [0x41e459] > > /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed) [0x7fa4c9f7676d] > > uwsgi() [0x41e489] > > *** end of backtrace *** > > > > direi che non hai il modulo greenlet nel venv > > -- > Roberto De Ioris > http://unbit.it > ___ > Python mailing list > Python@lists.python.it > http://lists.python.it/mailman/listinfo/python > ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
> Ok, come diceva Alessandro in realtà non siamo nemmeno riusciti a fare > dei test con uWSGI e il plugin perchè da errori di Segmentation Fault > usando --tornado 100 e --greenlet. Ma usando solo --tornado 100 da > questo errore: > *** DANGER *** tornado mode without coroutine/greenthread engine loaded > !!! > > Installato e abilitato con: > > UWSGI_EMBED_PLUGINS=tornado,greenlet pip install greenlet uwsgi > > Dopo aver installato i pacchetti python-greenlet e python-greenlet-dev > visto che senza diceva di non trovare greenlet/greenlet.h > > Qui sotto mette le informazioni che penso siano utili. > > > # uname -a > > Linux wadev 3.2.0-57-generic #87-Ubuntu SMP Tue Nov 12 21:35:10 UTC 2013 > x86_64 x86_64 x86_64 GNU/Linux > - > > > # uwsgi.ini > > [uwsgi] > socket = 127.0.0.1:9090 > uid = service > gid = service > pythonpath = /usr/local/python/Lib > virtualenv = /dati/wall > chdir = /dati/wall/src/test > wsgi-file = uwsgi_test.py > processes = 4 > threads = 2 > stats = 127.0.0.1:9191 > tornado = 100 > greenlet = > > ## Da risposta trovata in rete a proposito di Segmentation Fault. > ;master = true > ;enable-threads = true > ;singe-interpreter = true > > > # backtrace > > [uWSGI] getting INI configuration from uwsgi.ini > *** Starting uWSGI 2.0 (64bit) on [Fri Jan 3 13:07:47 2014] *** > compiled with version: 4.6.3 on 03 January 2014 09:42:28 > os: Linux-3.2.0-57-generic #87-Ubuntu SMP Tue Nov 12 21:35:10 UTC 2013 > nodename: wadev > machine: x86_64 > clock source: unix > pcre jit disabled > detected number of CPU cores: 2 > current working directory: /usr/wall/wall > detected binary path: /usr/wall/wall/bin/uwsgi > setgid() to 1005 > set additional group 27 (sudo) > setuid() to 1005 > your processes number limit is 15866 > your memory page size is 4096 bytes > detected max file descriptor number: 1024 > - async cores set to 100 - fd table size: 1024 > lock engine: pthread robust mutexes > thunder lock: disabled (you can enable it with --thunder-lock) > uwsgi socket 0 bound to TCP address 127.0.0.1:9090 fd 3 > Python version: 2.7.3 (default, Sep 26 2013, 20:13:52) [GCC 4.6.3] > Set PythonHome to /dati/wall > Python main interpreter initialized at 0xa28aa0 > python threads support enabled > your server socket listen backlog is limited to 100 connections > your mercy for graceful operations on workers is 60 seconds > mapped 415280 bytes (405 KB) for 8 cores > *** Operational MODE: preforking+threaded *** > added /usr/local/python/Lib/ to pythonpath. > WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0xa28aa0 pid: > 27566 (default app) > !!! uWSGI process 27566 got Segmentation Fault !!! > *** backtrace of 27566 *** > uwsgi(uwsgi_backtrace+0x29) [0x467b69] > uwsgi(uwsgi_segfault+0x21) [0x467cf1] > /lib/x86_64-linux-gnu/libc.so.6(+0x364a0) [0x7fa4c9f8b4a0] > uwsgi() [0x4a6494] > uwsgi(uwsgi_init_all_apps+0xcf) [0x46897f] > uwsgi(uwsgi_start+0xe6a) [0x4699fa] > uwsgi(uwsgi_setup+0x1885) [0x46b955] > uwsgi(main+0x9) [0x41e459] > /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed) [0x7fa4c9f7676d] > uwsgi() [0x41e489] > *** end of backtrace *** > direi che non hai il modulo greenlet nel venv -- Roberto De Ioris http://unbit.it ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
Ok, come diceva Alessandro in realtà non siamo nemmeno riusciti a fare dei test con uWSGI e il plugin perchè da errori di Segmentation Fault usando --tornado 100 e --greenlet. Ma usando solo --tornado 100 da questo errore: *** DANGER *** tornado mode without coroutine/greenthread engine loaded !!! Installato e abilitato con: UWSGI_EMBED_PLUGINS=tornado,greenlet pip install greenlet uwsgi Dopo aver installato i pacchetti python-greenlet e python-greenlet-dev visto che senza diceva di non trovare greenlet/greenlet.h Qui sotto mette le informazioni che penso siano utili. # uname -a Linux wadev 3.2.0-57-generic #87-Ubuntu SMP Tue Nov 12 21:35:10 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux - # uwsgi.ini [uwsgi] socket = 127.0.0.1:9090 uid = service gid = service pythonpath = /usr/local/python/Lib virtualenv = /dati/wall chdir = /dati/wall/src/test wsgi-file = uwsgi_test.py processes = 4 threads = 2 stats = 127.0.0.1:9191 tornado = 100 greenlet = ## Da risposta trovata in rete a proposito di Segmentation Fault. ;master = true ;enable-threads = true ;singe-interpreter = true # backtrace [uWSGI] getting INI configuration from uwsgi.ini *** Starting uWSGI 2.0 (64bit) on [Fri Jan 3 13:07:47 2014] *** compiled with version: 4.6.3 on 03 January 2014 09:42:28 os: Linux-3.2.0-57-generic #87-Ubuntu SMP Tue Nov 12 21:35:10 UTC 2013 nodename: wadev machine: x86_64 clock source: unix pcre jit disabled detected number of CPU cores: 2 current working directory: /usr/wall/wall detected binary path: /usr/wall/wall/bin/uwsgi setgid() to 1005 set additional group 27 (sudo) setuid() to 1005 your processes number limit is 15866 your memory page size is 4096 bytes detected max file descriptor number: 1024 - async cores set to 100 - fd table size: 1024 lock engine: pthread robust mutexes thunder lock: disabled (you can enable it with --thunder-lock) uwsgi socket 0 bound to TCP address 127.0.0.1:9090 fd 3 Python version: 2.7.3 (default, Sep 26 2013, 20:13:52) [GCC 4.6.3] Set PythonHome to /dati/wall Python main interpreter initialized at 0xa28aa0 python threads support enabled your server socket listen backlog is limited to 100 connections your mercy for graceful operations on workers is 60 seconds mapped 415280 bytes (405 KB) for 8 cores *** Operational MODE: preforking+threaded *** added /usr/local/python/Lib/ to pythonpath. WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0xa28aa0 pid: 27566 (default app) !!! uWSGI process 27566 got Segmentation Fault !!! *** backtrace of 27566 *** uwsgi(uwsgi_backtrace+0x29) [0x467b69] uwsgi(uwsgi_segfault+0x21) [0x467cf1] /lib/x86_64-linux-gnu/libc.so.6(+0x364a0) [0x7fa4c9f8b4a0] uwsgi() [0x4a6494] uwsgi(uwsgi_init_all_apps+0xcf) [0x46897f] uwsgi(uwsgi_start+0xe6a) [0x4699fa] uwsgi(uwsgi_setup+0x1885) [0x46b955] uwsgi(main+0x9) [0x41e459] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed) [0x7fa4c9f7676d] uwsgi() [0x41e489] *** end of backtrace *** Grazie, Luca Il giorno 03 gennaio 2014 12:50, Roberto De Ioris ha scritto: > > > On Mon, Dec 30, 2013 at 05:26:57PM +0100, Roberto De Ioris wrote: > >> > Mi pare di capire che la soluzione della listen queue che mi hai > >> indicato > >> > risolverebbe questo problema. > >> > > >> > >> > >> server = HTTPServer(app) > >> server.bind(post, backlog=1) > >> > >> (prova anche con zero, su alcuni kernel funziona, anche se non ricordo > >> se > >> e' per quelli piu' recenti o quelli piu' vecchi) > > > > Purtroppo questa strada non ha funzionato. Ricordo che il probelma che > > cerchiamo di risolvere è che quando viene interrotto una chiamata > "lunga", > > nginx libera quella connessione e quindi diritta verso quel processo la > > prossima chiamata, ma il processo di fatto è occupato. > > > > La nostra simulazione è stata fatta con 2 funzioni: is_up e blocking che > > usa > > time.sleep() > > > >class IsUp(tornado.web.RequestHandler): > >def get(self): > >self.write("Is Up Porta %d" ...) > > self.finish() > > > >class Blocking(tornado.web.RequestHandler): > >def get(self, numero=10): > >time.sleep(int(numero)) > > self.write("Bloccato Porta %s\n" % options.port) > > self.finish() > > > > la chiamata usando 'wget -q -O - http://ngtest/blocking/30/' ed > > interrompendolo con Control-c. > > In un terminale separato in ciclo di 'wget -q -O - http://ngtest/is_up' > > Il ciclo si blocca nel momento della interruzione e riprende solo quando > > termita il tempo (e quindi il processo si libera) > > provate a ridurre a 3 secondi il proxy_connect_timeout di nginx, e' > probabile che abbiate sempre almeno uno slot listen_queue libero anche se > lo avete impostato a 1/0. In questo modo se la connessione non completa in
Re: [Python] Deploy con nginx e proxy_pass
> On Mon, Dec 30, 2013 at 05:26:57PM +0100, Roberto De Ioris wrote: >> > Mi pare di capire che la soluzione della listen queue che mi hai >> indicato >> > risolverebbe questo problema. >> > >> >> >> server = HTTPServer(app) >> server.bind(post, backlog=1) >> >> (prova anche con zero, su alcuni kernel funziona, anche se non ricordo >> se >> e' per quelli piu' recenti o quelli piu' vecchi) > > Purtroppo questa strada non ha funzionato. Ricordo che il probelma che > cerchiamo di risolvere è che quando viene interrotto una chiamata "lunga", > nginx libera quella connessione e quindi diritta verso quel processo la > prossima chiamata, ma il processo di fatto è occupato. > > La nostra simulazione è stata fatta con 2 funzioni: is_up e blocking che > usa > time.sleep() > >class IsUp(tornado.web.RequestHandler): >def get(self): >self.write("Is Up Porta %d" ...) > self.finish() > >class Blocking(tornado.web.RequestHandler): >def get(self, numero=10): >time.sleep(int(numero)) > self.write("Bloccato Porta %s\n" % options.port) > self.finish() > > la chiamata usando 'wget -q -O - http://ngtest/blocking/30/' ed > interrompendolo con Control-c. > In un terminale separato in ciclo di 'wget -q -O - http://ngtest/is_up' > Il ciclo si blocca nel momento della interruzione e riprende solo quando > termita il tempo (e quindi il processo si libera) provate a ridurre a 3 secondi il proxy_connect_timeout di nginx, e' probabile che abbiate sempre almeno uno slot listen_queue libero anche se lo avete impostato a 1/0. In questo modo se la connessione non completa in 3 secondi, nginx considera il peer morto (e passa a quello dopo se lo avete configurato a dovere) > Credo di capire che vengono descritte più opzioni di configurazione: con i > greenlet ed una programmazione asincrona o con processi tornado > indipendenti. guarda terrei questo approccio proprio come ultima spiaggia (e probabilmente e' piu' semplice modificare tornado) se la osluzione sopra non dovesse funzionare -- Roberto De Ioris http://unbit.it ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
On 03/01/2014 12:34, Alessandro Dentella wrote: [...] La nostra simulazione è stata fatta con 2 funzioni: is_up e blocking che usa time.sleep() class IsUp(tornado.web.RequestHandler): def get(self): self.write("Is Up Porta %d" ...) self.finish() class Blocking(tornado.web.RequestHandler): def get(self, numero=10): time.sleep(int(numero)) self.write("Bloccato Porta %s\n" % options.port) self.finish() la chiamata usando 'wget -q -O - http://ngtest/blocking/30/' ed interrompendolo con Control-c. Ok. Ma quante instanze di tornado hai attive? Se ne hai attiva una sola, mi sembra ovvio che blocca tutto. Se ne hai N, facendo N richieste di questo genere blocchi ancora tutto. In un terminale separato in ciclo di 'wget -q -O - http://ngtest/is_up' Il ciclo si blocca nel momento della interruzione e riprende solo quando termita il tempo (e quindi il processo si libera) Che ciclo? > [...] Per concludere, tieni conto che usare cose come Tornado è tutt'altro che banale. Tutto lo stack (applicazione + framework + eventuali librerie) deve essere sviluppato con la programmazione asincrona in mente. E' vero che ci sono dei monkey patch per alcune funzioni della libreria standard, ma non ritengo sia saggio affidarsi ciecamente a loro. Python e la libreria standard semplicemente non sono pensati per un ambiente a green thread. Ciao Manlio ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
On Mon, Dec 30, 2013 at 05:26:57PM +0100, Roberto De Ioris wrote: > > Mi pare di capire che la soluzione della listen queue che mi hai indicato > > risolverebbe questo problema. > > > > > server = HTTPServer(app) > server.bind(post, backlog=1) > > (prova anche con zero, su alcuni kernel funziona, anche se non ricordo se > e' per quelli piu' recenti o quelli piu' vecchi) Purtroppo questa strada non ha funzionato. Ricordo che il probelma che cerchiamo di risolvere è che quando viene interrotto una chiamata "lunga", nginx libera quella connessione e quindi diritta verso quel processo la prossima chiamata, ma il processo di fatto è occupato. La nostra simulazione è stata fatta con 2 funzioni: is_up e blocking che usa time.sleep() class IsUp(tornado.web.RequestHandler): def get(self): self.write("Is Up Porta %d" ...) self.finish() class Blocking(tornado.web.RequestHandler): def get(self, numero=10): time.sleep(int(numero)) self.write("Bloccato Porta %s\n" % options.port) self.finish() la chiamata usando 'wget -q -O - http://ngtest/blocking/30/' ed interrompendolo con Control-c. In un terminale separato in ciclo di 'wget -q -O - http://ngtest/is_up' Il ciclo si blocca nel momento della interruzione e riprende solo quando termita il tempo (e quindi il processo si libera) > >> L'approccio migliore (o meglio diciamo quello risolutivo) e' che i > >> processi usino lo stesso socket, puoi provare il plugin tornado di > >> uWSGI: > >> > >> http://uwsgi-docs.readthedocs.org/en/latest/Tornado.html Siamo passato quindi a leggere la documentazione per fare questa prova ma ammetto che ho qualche dubbio. Dimmi per cortesia se scrivo inesattezze... Credo di capire che vengono descritte più opzioni di configurazione: con i greenlet ed una programmazione asincrona o con processi tornado indipendenti. Considerando che il tutto nasce proprio dal fatto che abbiamo probelmi nelle funzioni che NON sono state scritte in modo asincrono quello che vogliamo è di usare la configurazione descritta in fondo "Binding and listening with Tornado". Mi pare di capire che in questa ipotesi vengano fatti partire processi differenti e per ogni processo venga eseguito "start_the_tornado_servers", finiremmo quindi -come ora- ad avere svariati server tornado in ascolto ma con la differenza che il routing fra un server e l'altro sarebbe gestito da uwsgi, corretto? è in questa situazione che uwsgi usa lo stesso socket per tutti i processi? *Se* fin qui e` corretto mi resta poi da capire come mai 'start_the_tornado_servers' lanci application e non 't_application' e come construire la application che viene chiamata da uwsgi. Nell'esempio i 3 puntini presuppongono un lettore meno confuso del sottoscritto... Lascio poi al mio collega un'altra domanda su un probelma di segfault... grazie per l'attenzione sandro *:-) ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
> On Tue, Dec 24, 2013 at 11:58:05AM +0100, Roberto De Ioris wrote: >> >> >> > >> > io sono convinto che se il modello resta round robbin puro, anche se >> > raddoppiassi i processi avrei solo dimezzato la probabilità di >> incapare in >> > una chiamata "lunga", mentre se potessi evitare di passare chiamate ad >> un >> > processo che sta lavorando eviterei proprio questa cosa. >> > >> > >> >> aggancia una strace ai processi tornado durante un blocco per vedere >> che >> >> succede. Probabilmente non ci sara' molto da fare se non aggiungere >> >> altri >> >> processi tornado (sempre che sia tollerabile dall'applicazione). >> > >> > le chiamate lunghe non sono chiamate che a random prendono tanto >> tempo, >> > sono >> > chiamate che "fanno molte cose" probabilmente non ottimizzate, ma >> sulle >> > quali io non ho diretto controllo (sono inizializzazioni mensili di >> alcune >> > posizioni). >> > >> > Grazie per il suggeriemnto >> > sandro >> > *:-) >> >> Nginx non puo' farlo (vedi pero' nota sotto) >> >> L'approccio migliore (o meglio diciamo quello risolutivo) e' che i >> processi usino lo stesso socket, puoi provare il plugin tornado di >> uWSGI: >> >> http://uwsgi-docs.readthedocs.org/en/latest/Tornado.html >> >> ma non e' compilato di default (per motivi altamente tecnici: ovvero >> odio >> la programmazione callback based e non voglio incentivarla ulteriormente >> ;) >> >> anche gunicorn ha un worker model per tornado ma e' deprecato (ma >> presumo >> funzioni ancora) >> >> Nota: >> Se abbassi la listen queue del socket dentro tornado a 1 (in alcuni >> kernel >> puoi metterla anche a 0 che sarebeb addirittura meglio), otterrai subito >> un errore in caso di worker occupato e nginx passera' la richiesta al >> backend successivo. E' un buon trucco (anche se poco diffuso) nel tuo >> caso >> specifico. > > Grazie Roberto, > > non mi è chiaro se il suggerimento di abbassare la listen queue possa > essere > usato indipendentemente da uwsgi (come credo). In questo caso non ho > capito > come farlo. Non ho trovato parametri di tornado. Credo che quello che > suggerisci sia poi la backlog della socket.listen() ma veramente non ho > alcuna competenza di questo campo... > > > Al momento, dopo essere passato a nginx 1.4+, un tornado minimale di test > con 2 handler uno che risponde subito e l'altro che si blocca, arrivo ad > una > situazione ottimale fino a che uno abortisce la richiesta. A quel punto > ho > la sensazione che nginx azzeri la lista di connessione attive per una > porta > particolare mentre tornado resta appeso. Nginx passa la prossima chiamata > a > quella porta ed il tutto si blocca. > > Mi pare di capire che la soluzione della listen queue che mi hai indicato > risolverebbe questo problema. > server = HTTPServer(app) server.bind(post, backlog=1) (prova anche con zero, su alcuni kernel funziona, anche se non ricordo se e' per quelli piu' recenti o quelli piu' vecchi) -- Roberto De Ioris http://unbit.it ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
On Tue, Dec 24, 2013 at 11:58:05AM +0100, Roberto De Ioris wrote: > > > > > > io sono convinto che se il modello resta round robbin puro, anche se > > raddoppiassi i processi avrei solo dimezzato la probabilità di incapare in > > una chiamata "lunga", mentre se potessi evitare di passare chiamate ad un > > processo che sta lavorando eviterei proprio questa cosa. > > > > > >> aggancia una strace ai processi tornado durante un blocco per vedere che > >> succede. Probabilmente non ci sara' molto da fare se non aggiungere > >> altri > >> processi tornado (sempre che sia tollerabile dall'applicazione). > > > > le chiamate lunghe non sono chiamate che a random prendono tanto tempo, > > sono > > chiamate che "fanno molte cose" probabilmente non ottimizzate, ma sulle > > quali io non ho diretto controllo (sono inizializzazioni mensili di alcune > > posizioni). > > > > Grazie per il suggeriemnto > > sandro > > *:-) > > Nginx non puo' farlo (vedi pero' nota sotto) > > L'approccio migliore (o meglio diciamo quello risolutivo) e' che i > processi usino lo stesso socket, puoi provare il plugin tornado di uWSGI: > > http://uwsgi-docs.readthedocs.org/en/latest/Tornado.html > > ma non e' compilato di default (per motivi altamente tecnici: ovvero odio > la programmazione callback based e non voglio incentivarla ulteriormente > ;) > > anche gunicorn ha un worker model per tornado ma e' deprecato (ma presumo > funzioni ancora) > > Nota: > Se abbassi la listen queue del socket dentro tornado a 1 (in alcuni kernel > puoi metterla anche a 0 che sarebeb addirittura meglio), otterrai subito > un errore in caso di worker occupato e nginx passera' la richiesta al > backend successivo. E' un buon trucco (anche se poco diffuso) nel tuo caso > specifico. Grazie Roberto, non mi è chiaro se il suggerimento di abbassare la listen queue possa essere usato indipendentemente da uwsgi (come credo). In questo caso non ho capito come farlo. Non ho trovato parametri di tornado. Credo che quello che suggerisci sia poi la backlog della socket.listen() ma veramente non ho alcuna competenza di questo campo... Al momento, dopo essere passato a nginx 1.4+, un tornado minimale di test con 2 handler uno che risponde subito e l'altro che si blocca, arrivo ad una situazione ottimale fino a che uno abortisce la richiesta. A quel punto ho la sensazione che nginx azzeri la lista di connessione attive per una porta particolare mentre tornado resta appeso. Nginx passa la prossima chiamata a quella porta ed il tutto si blocca. Mi pare di capire che la soluzione della listen queue che mi hai indicato risolverebbe questo problema. sandro *:-) PS: ho letto la documentazione del plugin di tornado di uWSGI, mi pare relativamete semplice ma non ho ancora avuto tempo di provarla ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
On 24/12/2013 11:58, Roberto De Ioris wrote: [...] L'approccio migliore (o meglio diciamo quello risolutivo) e' che i processi usino lo stesso socket, puoi provare il plugin tornado di uWSGI: http://uwsgi-docs.readthedocs.org/en/latest/Tornado.html ma non e' compilato di default (per motivi altamente tecnici: ovvero odio la programmazione callback based e non voglio incentivarla ulteriormente ;) Eh, purtroppo l'approccio a callback con macchina a stati è l'unico possibile se vuoi portabilità ed efficienza. Rassegnamoci ;) > [...] Ciao Manlio ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
> > io sono convinto che se il modello resta round robbin puro, anche se > raddoppiassi i processi avrei solo dimezzato la probabilità di incapare in > una chiamata "lunga", mentre se potessi evitare di passare chiamate ad un > processo che sta lavorando eviterei proprio questa cosa. > > >> aggancia una strace ai processi tornado durante un blocco per vedere che >> succede. Probabilmente non ci sara' molto da fare se non aggiungere >> altri >> processi tornado (sempre che sia tollerabile dall'applicazione). > > le chiamate lunghe non sono chiamate che a random prendono tanto tempo, > sono > chiamate che "fanno molte cose" probabilmente non ottimizzate, ma sulle > quali io non ho diretto controllo (sono inizializzazioni mensili di alcune > posizioni). > > Grazie per il suggeriemnto > sandro > *:-) Nginx non puo' farlo (vedi pero' nota sotto) L'approccio migliore (o meglio diciamo quello risolutivo) e' che i processi usino lo stesso socket, puoi provare il plugin tornado di uWSGI: http://uwsgi-docs.readthedocs.org/en/latest/Tornado.html ma non e' compilato di default (per motivi altamente tecnici: ovvero odio la programmazione callback based e non voglio incentivarla ulteriormente ;) anche gunicorn ha un worker model per tornado ma e' deprecato (ma presumo funzioni ancora) Nota: Se abbassi la listen queue del socket dentro tornado a 1 (in alcuni kernel puoi metterla anche a 0 che sarebeb addirittura meglio), otterrai subito un errore in caso di worker occupato e nginx passera' la richiesta al backend successivo. E' un buon trucco (anche se poco diffuso) nel tuo caso specifico. Altro approccio e' ridurre il proxy_connect_timeout, ma trovare il giusto compromesso sul valore e' dura -- Roberto De Ioris http://unbit.it ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
On Tue, Dec 24, 2013 at 09:19:19AM +0100, Roberto De Ioris wrote: > > > Ciao a tutti, > > > > ho bisogno di capire una configurazione di un webs server nginx di un > > cliente che usa proxy_pass passando come destinatario > > > > upstream produzione { > > server 127.0.0.1:8080; > > server 127.0.0.1:8081; > > ... > > } > > proxy_pass http://produzione; > > > > > > Quello che vorrei capire è come funziona e se è configurabile il > > meccanismo > > di assegnazione della richiesta ai vari server. > > > > Il problema nasce dal fatto che hanno una applicazione fatta con tornado > > ma > > con chiamate non asincrone, ed una base di codice che si sono sviluppati > > negli anni e che non hanno il coraggio/determinazione di cambiare. > > il 99% delle funzioni prende meno di 1 secondo ma acunin prendono anche 10 > > secondi fino a 25 e questo è accettabile. > > > > Il problema nasce dal fatto che in alcuni casi sperimentano dei blocchi. > > > > La mia sensazione (e qui paleso la mia ignoranza in merito) è che nginx > > faccia round robbin fra i 10 processi esistenti e non stia a guardare se > > hanno terminato o meno la precedente richiesta. Esiste un modo di forzare > > uno schema per cui vengano serviti solo i processi che non hanno in corso > > una elaborazione? > > > > NB: non esiste un problema di troppo carico, il server è sostanzialmente > > sottosfruttato, il sito non ha un carico elevato > > > > Sono graditi anche puntatori a letture illuminanti... > > > > grazie > > sandro > > *:-) > > ___ > > > > Nelle release > 1.3 di nginx puoi impostare il least connections come > algoritmo: > > http://nginx.org/en/docs/http/ngx_http_upstream_module.html#least_conn grazie, leggo nella doc: Specifies that a group should use a load balancing method where a request is passed to the server with the least number of active connections, taking into account weights of servers. If there are several such servers, they are tried using a weighted round-robin balancing method. ed immagino che le active connections siano esattamente quelle in elaborazione. Considerando che ho 10 processi, il 99% delle richieste viene espletato in meno di 1 secondo e ho un rate che nelle ore "di punta" arriva a 2/secondo credo che sia molto probabile che ci sia sempre un processo libero e che quindi questo venga scelto da questo algoritmo, se lo capisco correttamente. > ma ho seri dubbi che il problema sia li', appena hai scritto "tornado con > chiamate non asincrone", hai praticamente descritto IL problema ;) Vero, ma questa è una eredità su cui non ho potere... per bypassarlo avevo modificato il codice per potere girare con svariati (10 al momento) processi indipendenti, ora è così ed in effetti la situazione è abbastanza gestibile con l'eccezione dei blocchi descritti sopra. io sono convinto che se il modello resta round robbin puro, anche se raddoppiassi i processi avrei solo dimezzato la probabilità di incapare in una chiamata "lunga", mentre se potessi evitare di passare chiamate ad un processo che sta lavorando eviterei proprio questa cosa. > aggancia una strace ai processi tornado durante un blocco per vedere che > succede. Probabilmente non ci sara' molto da fare se non aggiungere altri > processi tornado (sempre che sia tollerabile dall'applicazione). le chiamate lunghe non sono chiamate che a random prendono tanto tempo, sono chiamate che "fanno molte cose" probabilmente non ottimizzate, ma sulle quali io non ho diretto controllo (sono inizializzazioni mensili di alcune posizioni). Grazie per il suggeriemnto sandro *:-) -- Sandro Dentella *:-) http://www.reteisi.org Soluzioni libere per le scuole http://sqlkit.argolinux.orgSQLkit home page - PyGTK/python/sqlalchemy sandro *:-) ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Deploy con nginx e proxy_pass
> Ciao a tutti, > > ho bisogno di capire una configurazione di un webs server nginx di un > cliente che usa proxy_pass passando come destinatario > > upstream produzione { > server 127.0.0.1:8080; > server 127.0.0.1:8081; > ... > } > proxy_pass http://produzione; > > > Quello che vorrei capire è come funziona e se è configurabile il > meccanismo > di assegnazione della richiesta ai vari server. > > Il problema nasce dal fatto che hanno una applicazione fatta con tornado > ma > con chiamate non asincrone, ed una base di codice che si sono sviluppati > negli anni e che non hanno il coraggio/determinazione di cambiare. > il 99% delle funzioni prende meno di 1 secondo ma acunin prendono anche 10 > secondi fino a 25 e questo è accettabile. > > Il problema nasce dal fatto che in alcuni casi sperimentano dei blocchi. > > La mia sensazione (e qui paleso la mia ignoranza in merito) è che nginx > faccia round robbin fra i 10 processi esistenti e non stia a guardare se > hanno terminato o meno la precedente richiesta. Esiste un modo di forzare > uno schema per cui vengano serviti solo i processi che non hanno in corso > una elaborazione? > > NB: non esiste un problema di troppo carico, il server è sostanzialmente > sottosfruttato, il sito non ha un carico elevato > > Sono graditi anche puntatori a letture illuminanti... > > grazie > sandro > *:-) > ___ > Nelle release > 1.3 di nginx puoi impostare il least connections come algoritmo: http://nginx.org/en/docs/http/ngx_http_upstream_module.html#least_conn ma ho seri dubbi che il problema sia li', appena hai scritto "tornado con chiamate non asincrone", hai praticamente descritto IL problema ;) aggancia una strace ai processi tornado durante un blocco per vedere che succede. Probabilmente non ci sara' molto da fare se non aggiungere altri processi tornado (sempre che sia tollerabile dall'applicazione). -- Roberto De Ioris http://unbit.it ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
[Python] Deploy con nginx e proxy_pass
Ciao a tutti, ho bisogno di capire una configurazione di un webs server nginx di un cliente che usa proxy_pass passando come destinatario upstream produzione { server 127.0.0.1:8080; server 127.0.0.1:8081; ... } proxy_pass http://produzione; Quello che vorrei capire è come funziona e se è configurabile il meccanismo di assegnazione della richiesta ai vari server. Il problema nasce dal fatto che hanno una applicazione fatta con tornado ma con chiamate non asincrone, ed una base di codice che si sono sviluppati negli anni e che non hanno il coraggio/determinazione di cambiare. il 99% delle funzioni prende meno di 1 secondo ma acunin prendono anche 10 secondi fino a 25 e questo è accettabile. Il problema nasce dal fatto che in alcuni casi sperimentano dei blocchi. La mia sensazione (e qui paleso la mia ignoranza in merito) è che nginx faccia round robbin fra i 10 processi esistenti e non stia a guardare se hanno terminato o meno la precedente richiesta. Esiste un modo di forzare uno schema per cui vengano serviti solo i processi che non hanno in corso una elaborazione? NB: non esiste un problema di troppo carico, il server è sostanzialmente sottosfruttato, il sito non ha un carico elevato Sono graditi anche puntatori a letture illuminanti... grazie sandro *:-) ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python