29 messaggi dal 19 gennaio 2007
Ciao a tutti!
Chiedo un vostro parere riguardo alla seguente situazione.
Ho un'applicazione web con un'attività media di 3 nuove sessioni al minuto (sessioni che durano 20min). Per ogni sessione salvo in Session (inprocess) una lista di oggetti piuttosto complesso (necessari per una corretta navigazione) per un totale di circa 500KB a sessione (stima dello spazio usato ottenuto dalla serializzazione binaria della stessa).
Appena riciclato l'application pool (Framework 4), il relativo processo pesa circa 190MB. Dopo un'ora di utilizzo arrivo a 400MB circa e li si stabilizza oscillando di poco.
Appena avviata l'applicazione (riciclo dell'application pool) ogni chiamata è pressoché istantanea.
Invece, dopo qualche ora di utilizzo (e dopo aver servito qualche centinaio di sessioni), ogni richiesta effettuata al server richiede svariati secondi, fino a rendere l'utilizzo dell'applicazione davvero frustrante.
Analizzando il Trace della chiamata di una pagina, noto che il 98% del tempo speso avviene in Page_Init. Tale tempo è speso anche chiamando una pagina completamente vuota. In questo contesto noto un forte utilizzo di CPU (server dedicato), fino a raggiungere livelli critici di performance di tutto il server.
Riciclando l'application pool tutto torna ad essere istantaneo.

Mi sapreste dare qualche indicazione in merito?
Quali potrebbero essere le potenziali cause di un simile scenario?
Ogni suggerimento o esperienza passata simile è ben accetta!
Grazie mille!
Modificato da stewe il 05 giugno 2014 19.33 -

·..·`·Stewe·`·..·
11.884 messaggi dal 09 febbraio 2002
Contributi
Ciao,

stewe ha scritto:

il 98% del tempo speso avviene in Page_Init. Tale tempo è speso anche chiamando una pagina completamente vuota.

Controlla meglio usando il tracing di ASP.NET o il profiler di Visual Studio. Casomai posta i dati che riesci a raccogliere.

Comprendi bene che se la funzione Page_Init è vuota, cioè non ha istruzioni al suo interno, non può rallentare in alcun modo l'esecuzione del thread. Forse il problema è altrove, come su eventuali operazioni che svolgi nel Session_Start del global.asax, oppure in un HttpModule.

stewe ha scritto:

per un totale di circa 500KB a sessione

Mi sembra molto, ma non conoscendo la tua applicazione non posso stabilire se quei 500KB siano evitabili o meno.
Ad ogni modo, questi oggetti *non dovrebbero* essere la causa del problema perché quando usi la modalità in-process, non avviene alcuna (de)serializzazione e quindi l'accesso a tali oggetti dovrebbe essere sempre abbastanza rapido (finché c'è sufficiente RAM disponibile).

ciao,
Moreno
Modificato da BrightSoul il 07 giugno 2014 11.33 -

Enjoy learning and just keep making
29 messaggi dal 19 gennaio 2007
Controlla meglio usando il tracing di ASP.NET o il profiler di Visual Studio. Casomai posta i dati che riesci a raccogliere.

Comprendi bene che se la funzione Page_Init è vuota, cioè non ha istruzioni al suo interno, non può rallentare in alcun modo l'esecuzione del thread. Forse il problema è altrove, come su eventuali operazioni che svolgi nel Session_Start del global.asax, oppure in un HttpModule.


Il metodo Page_Init è vuoto, come anche Session_Start.
Utilizzo controlli di terze parti, quindi il problema potrebbe esser dovuto ad un bug sul loro codice.

Di seguito il trace:

Categoria Messaggio Dai primi Dagli ultimi
aspx.page End PreInitaspx.page Begin Init 0,00 0,00
aspx.page End Init 5,37 5,37
aspx.page Begin InitComplete 5,37 0,00
aspx.page End InitComplete 5,37 0,00
aspx.page Begin PreLoad 5,38 0,00
aspx.page End PreLoad 5,38 0,00
aspx.page Begin Load 5,38 0,00
aspx.page End Load 8,68 3,30
aspx.page Begin LoadComplete 8,68 0,00
aspx.page End LoadComplete 8,68 0,00
aspx.page Begin PreRender 8,68 0,00
aspx.page End PreRender 13,70 5,02
aspx.page Begin PreRenderComplete 13,70 0,00
aspx.page End PreRenderComplete 13,70 0,00
aspx.page Begin SaveState 13,86 0,16
aspx.page End SaveState 13,87 0,01
aspx.page Begin SaveStateComplete 13,87 0,00
aspx.page End SaveStateComplete 13,87 0,00
aspx.page Begin Render 13,87 0,00
aspx.page End Render 14,17 0,30

Il Page_Init è istantaneo appena avviato l'applicativo, poi, man mano che si servono utenti le prestazioni calano ed il ritardo accumulato in quel punto aumenta. Dopo circa 1000 sessioni servite (e solo una decina di sessioni attive) ottengo il ritardo di oltre 5 sec.
La pagina tracciata è la più complessa dell'applicativo e conta oltre 700 check su una singola pagina.
Le cause dei 3.3 sec nel load sono già state individuate e sono già al lavoro sull'ottimizzazione di alcuni metodi richiamati.
Anche la fase di PreRendering sembra esser critica, ma essendo la pagina piuttosto corposa, potrebbe anche starci...

Non ho mai avuto occasione di usare il Profiler... faccio qualche prova.

Mi sembra molto, ma non conoscendo la tua applicazione non posso stabilire se quei 500KB siano evitabili o meno.
Ad ogni modo, questi oggetti *non dovrebbero* essere la causa del problema perché quando usi la modalità in-process, non avviene alcuna (de)serializzazione e quindi l'accesso a tali oggetti dovrebbe essere sempre abbastanza rapido (finché c'è sufficiente RAM disponibile).


I 500KB sono evitabili riscrivendo la logica dell'applicazione. Non avendo avuto fino ad oggi evidenza di problemi dovuti ad un uso un po' più corposo della Session ho deciso di avvalermi ed usare gli oggetti provenienti direttamente dal Business Layer.
La Ram disponibile sul server è sufficiente a servire un numero nettamente superiore di utenti di quelli effettivamente da servire nelle condizioni più pessimistiche.
Modificato da stewe il 09 giugno 2014 10.30 -
Modificato da stewe il 09 giugno 2014 10.30 -

·..·`·Stewe·`·..·
29 messaggi dal 19 gennaio 2007
Ho dato un'occhiata al profiler. La mia analisi è sicuramente poco attendibile essendo neofita di tale strumento.
Ad ogni modo, noto che l'88% del tempo viene speso nella chiamata di metodi all'interno delle DLL dei controlli di terze parti.
Eliminando un Popup e relativo UpdatePanel interno (facenti parte di questa collezione di controlli) il problema sembra risolversi.
Sto valutando di riscrivere parte del programma evitando questi controlli.

·..·`·Stewe·`·..·
11.884 messaggi dal 09 febbraio 2002
Contributi
Ciao,


Eliminando un Popup e relativo UpdatePanel interno (facenti parte di questa collezione di controlli) il problema sembra risolversi.

Ok, ma dedica un po' di tempo per fare una ricerca più approfondita perché potrebbe essere il sintomo di un problema più profondo, che potrebbe ripresentartisi sotto altre forme, anche facendo a meno di quei controlli.

Se grazie al profiler sei riuscito ad identificare qual è il metodo che richiede più tempo, vai ad aprire l'assembly di quei controlli con Just Decompile ed esamina le istruzioni contenute in tale metodo.
Quando riesci ad intuire la causa, puoi o risolverla autonomamente se dipende in qualche modo dalla tua applicazione, oppure farla presente nel forum del produttore di questi controlli, perché potresti effettivamente esserti imbattuto in un loro bug.

ciao,
Moreno

Enjoy learning and just keep making
29 messaggi dal 19 gennaio 2007
Ho terminato ora di riscrivere la porzione di codice che faceva uso del controllo incriminato. Ora sembra funzionare tutto correttamente.
Sicuramente creerò un progettino che riproduca lo stesso contesto e lo invierò al supporto per un'analisi.
Nel frattempo vedrò di approfondire le mie conoscenze in merito al profiler.

Grazie mille per i consigli!

·..·`·Stewe·`·..·

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.