2009-03-10 19 views
11

In corso in un problema in cui JSF sta riempiendo le nostre sessioni. Abbiamo avuto un crash del sistema l'altro giorno. Abbiamo inviato l'heap a IBM per la revisione e abbiamo scoperto che avevamo sessioni di dimensioni fino a 50M. Hanno trovato componenti JSF nella sessione e alcuni molto grandi.JSF Tuning

Quindi, c'è qualche ottimizzazione che si può fare? Elementi di configurazione da guardare? O altra direzione.

Il nostro sistema è stato creato utilizzando JSF e Spring per il livello di presentazione, il back-end è EJB, Spring e Hibernate tutti in esecuzione su WebSphere 6.1.

risposta

22

JSF è una tecnologia utile, ma puoi sicuramente impiccarti.

Sembra, o si sta gonfiando la dimensione dello stato di visualizzazione (impostando grandi valori sui componenti) o si stanno perdendo i riferimenti ai componenti in altri stati di sessione (che sarebbe male). Un altro potenziale colpevole sarebbe una visione eccessivamente ampia (ho visto che la facilità con cui le persone possono costruire alberi dell'interfaccia utente portano a grafici di controllo molto grandi con tabelle di dati ovunque). So che IBM fornisce controlli di testo e fogli di calcolo avanzati: non posso commentare quale effetto avrà l'uso di questi su dimensioni dello stato.

Il frutto di sospensione basso controlla i bean gestiti configurati per l'ambito di sessione in faces-config.xml.

JSF salva due cose tra le richieste:

  • la vista (tutti i controlli sulla pagina)
  • lo stato di visualizzazione (lo stato dei controlli)

Questi sono separati a causa alcuni controlli, come i figli di una tabella di dati, possono avere più stati (uno per ogni riga). Lo stato può essere salvato in un campo nascosto nel modulo (che, se non crittografato, può costituire un grosso rischio per la sicurezza) o nella sessione. Al fine di ospitare più finestre del browser che condividono la stessa sessione (e, in alcune implementazioni, il supporto del pulsante indietro), vengono memorizzate più viste.

  • Ci dovrebbe essere un'opzione di configurazione per impostare il numero di stati di visualizzazione che l'app manterrà nella sessione per un dato utente in qualsiasi momento.
  • È possibile misurare la dimensione dello stato di visualizzazione fornendo un StateManager che misura la dimensione della vista/stato salvati (configurare uno StateManager in faces-config.xml con un costruttore pubblico che accetta uno StateManager - vedi i PDF JSF spec per maggiori dettagli; lo stato è serializzabile e puoi controllarne le dimensioni scaricandolo in un flusso).

La maggior parte delle app JSF create da IDE dispongono di backing bean. Sarebbe possibile, tramite il bean di sessione, mantenere lo stato più a lungo di quanto si desideri, mettendo a dura prova la sessione. Poiché tende ad esserci un backing bean per pagina, più pagine hai, più grande sarà il problema. Controlla il tuo faces-config.xml per vedere se questa è una potenziale fonte di problemi.

Un'altra cosa che potresti fare sarebbe configurare un HttpSessionAttributeListener nel tuo web.xml. Puoi ottenere un stack trace per identificare le aree problematiche nella tua app.

3

Questo è il secondo sistema che ho sentito che è morto a causa di JSF e della creazione eccessiva di oggetti. L'altro ha anche usato Spring e Hibernate nella parte posteriore. La creazione di profili con OptimizeIt ha mostrato che la risposta del backend era dell'ordine di millisecondi per tutte le richieste, ma era possibile cronometrare il rendering del browser con il cronometro perché impiegava molto tempo - da 30 secondi a diversi minuti. La memoria consumata dal cliente era ridicola.

Ero solo un osservatore, non un membro di quel team di progetto. Dovrò chiedere se il problema è stato risolto e, in tal caso, quale potrebbe essere stata la soluzione.

Ma se due punti fanno tendenza, direi che JSF potrebbe essere fatalmente imperfetto. Personalmente, me ne sto lontano completamente.

Perché non provare un front end Web di primavera e vedere se questo aiuta? Se segui l'idioma Spring, dovrebbe essere relativamente semplice sostituire JSF con JSP basati su JSTL e controller Spring.

+0

solo un'opinione personale, ma penso che il difetto risieda nell'IBM e nella loro implementazione JSF. Non riesco a giustificare i miei sentimenti :) – guyumu

+0

Quello che ho visto fallito utilizzava la JVM Sun e l'implementazione JSF di Apache. Apache è pesantemente IBM, quindi non posso dire come i due siano diversi. Penso che sia il modello JSF: mi sembra molto pesante. – duffymo

3

Stavo lavorando a un progetto JSF e ho scoperto che c'era un bug in cui stavamo aggiungendo più elementi JSF h: form. Risultante in una copia dell'intero viewstate incluso in ogni modulo. Riducendo a 1 modulo per pagina, le pagine da ~ 2M sono scese a ~ 300K.

1

È possibile che si verifichino problemi con molti bean di supporto come ambito della sessione.

Si può provare a esaminare MyFaces Orchestra. Questa è una libreria che fornisce un ambito di conversazione, quindi una volta che un utente ha finito con un particolare gruppo di fagioli, questi verranno rimossi dalla sessione.

Capisco che Spring WebFlow ha caratteristiche simili ma non l'ho davvero studiato!

1

JSF memorizza le viste in sessione per supportare la sua architettura basata su componenti ricchi (necessario mantenere lo stato di visualizzazione) e potrebbe riempire l'heap se non utilizzato correttamente. Se non hai grandi flussi di lavoro, vai sempre con un piccolo numero di visualizzazioni per sessione. Evita anche di tenere i backingbeans in sessione il più possibile. Usa il tag personalizzato per rendere l'oggetto dati solo per il successivo ciclo di richiesta. Possiamo anche utilizzare Spring Web Flow con JSF, che introduce l'ambito di visualizzazione e l'ambito del flusso se disponiamo di lunghi flussi di lavoro nell'applicazione per ridurre il numero di visualizzazioni configurate in sessione. JSF può essere usato per creare facilmente un'interfaccia utente ricca, il che aiuta a creare un'applicazione Web simile all'applicazione desktop. Assegna un heap specifico al framework JSF per fare il suo lavoro. Ma usa la memoria in modo efficiente nel lato dell'applicazione e assicurati che non ci siano perdite di memoria. Tutte le perdite di memoria devono essere studiate e corrette durante lo sviluppo stesso. Usa sempre un profiler per trovare perdite di memoria e colli di bottiglia nelle prestazioni che esistono nell'applicazione.

Mat.

1

Se si utilizza MyFaces < 1.1.6, si verifica un'enorme perdita di memoria nel modo in cui memorizza nella cache le vecchie visualizzazioni serializzate nella sessione in modo efficace e non consente loro di rilasciarle in modo che possano essere raccolte automaticamente. Ho avuto un problema serio con quello e ho avuto anche sessioni da 50 Mb. Un rapido aggiornamento di MyFaces ha risolto il problema senza problemi.

1

Configurare il persistence di sessione nel database e utilizzerà l'algoritmo meno utilizzato per forzare l'esaurimento delle sessioni meno utilizzate. Ha alte prestazioni (se configurato correttamente) e ti aiuterà in modo conciso e veloce.

1

Bit di un vecchio argomento, ma ci siamo imbattuti recentemente in questo. Spesso, la vista e lo stato di visualizzazione vengono memorizzati (come accennato in precedenza) e riempiono la sessione per consentire il funzionamento del pulsante Indietro. Ci sono dei parametri per ordinare questo nei descrittori di distribuzione (web.xml) che devono essere impostati.

Più istanze di determinate librerie possono richiedere più di un'impostazione di parametro, ad esempio quando si utilizza MyFaces e JSF RI. Per impostazione predefinita, possono essere impostati su valori piuttosto elevati (rispettivamente 20 e 16, credo). Ciò significa che puoi usare 20 volte lo spazio per cui dovresti (parte di?) La sessione.

1

suggerimenti di tuning JSF per l'ambiente di produzione:
- L'uso di immagini, CSS e risorse JavaScript dovrebbe essere fatto da tag HTML standard (img,link,script) non sul lato server, ed essere sicuri di impostare #{request.contextPath} prima che l'URL per evitare i percorsi relativi problemi.
- Cache sezioni statica della pagina (menu,header,footer) utilizzando omnifaces cache
- Impostare refresh-period variabile a -1
- insieme project-stage di Produzione
- Rivedere le filtri codice eventuale

Inoltre, controllare il mio articolo "Java Server Faces in Real-Life Applications" su DZone, ti fornirà l'immagine completa di JSF negli ambienti di sviluppo, test e produzione.

+0

Grazie Shaz! , aggiornato. –