Come progettare servizi Web altamente scalabili in Java?

15

Sto creando alcuni servizi Web che avrebbero 2000 utenti simultanei. I servizi sono offerti gratuitamente e quindi ci si aspetta che ottengano una vasta base di utenti. In futuro potrebbe essere necessario scalare fino a 50.000 utenti.

Ci sono già alcune altre domande che affrontano il problema come: link

Tuttavia, i miei requisiti differiscono dalla domanda precedente.

Ad esempio - La mia applicazione non ha un'interfaccia utente, quindi le immagini, i CSS, javascript non sono un problema. È in Java quindi suggerimenti come usare HipHop per tradurre PHP in codice nativo sono inutili.

Quindi ho deciso di porre la mia domanda separatamente.

Questa è la configurazione del mio progetto -

  1. Servizi Web basati sul riposo con Apache CXF
  2. Hibernate 3.0 (con ottimizzazioni rilevanti come il lazy loading e l'HQL personalizzato per la messa a punto)
  3. Tomcat 6.0
  4. MySql 5.5

Quali sono le migliori pratiche da rispettare per rendere scalabile un'applicazione basata su Java?

    
posta Kshitiz Sharma 19.06.2012 - 07:56
fonte

3 risposte

8

Ho affrontato il problema in passato, ma sento ancora che ho molto da imparare sul campo. Trovo che questo sia uno dei campi più interessanti che ci siano nello sviluppo del software al giorno d'oggi, ecco alcune riflessioni su questo:
MySQL è giusto abbastanza database a meno che tu non stia lavorando con enormi quantità di dati, e in questo caso potresti prendere in considerazione il database NoSQL, ma dovresti esaminare attentamente qual è il miglior database NoSQL per tuo bisogni.
Dovresti implementare il caching nel tuo sistema - prova a memorizzare il più possibile il massimo possibile nella cache dei dati di sola lettura, o definisci alcune strategie di memorizzazione nella cache - ad esempio, avevamo uno scenario in cui era valido per un utente vedere "vecchi dati" come Finché il recente aggiornamento è avvenuto nell'ultima ora.
Vorrei prendere in considerazione JBoss Cache, o forse Infinispan (che è più simile a una struttura di dati distribuiti) o altro framework di caching popolare per questo.
Inoltre, come hai menzionato Tomcat, presumo che lavori in qualche modulo di richiesta di responso. Prova a considerare l'utilizzo di una cache che esiste nell'ambito di una determinata richiesta, questa può essere anche una semplice HashMap associata a stile di archiviazione locale .
La mia idea qui è abbastanza simile a cache di primo livello di Hibernate .   
Dovresti ricordare che i file, le transazioni e le altre risorse sono costose in termini di mantenimento della loro apertura. Assicurati di chiudere file e transazioni il prima possibile o finirai con bug che si riprodurranno su configurazioni su larga scala

Inoltre, è necessario comprendere quali utenti di 2000 utenti: ciò significa che 2000 utenti accedono al server contemporaneamente o utilizzano il sistema? Distinguere tra i casi in cui 2000 utenti tentano di aprire un socket sul proprio server e un caso in cui solo 500 sono, e 1500 stanno attualmente valutando i risultati, di riempire gli input sul lato client.
Dovresti considerare l'utilizzo del clustering - dovrai affrontare problemi come bilanciamento del carico , sessione persistente (che significa il servizio di bilanciamento del carico reindirizzerà una richiesta allo stesso server per la stessa sessione) e altro ancora.
Se è necessario disporre del codice di sincronizzazione, scegliere attentamente la strategia di sincronizzazione. Ho visto alcuni sistemi in cui è stato utilizzato un semplice blocco, ma un ReaderWriterLock potrebbe aver migliorato le cose, poiché la maggior parte degli accessi era di sola lettura.
Considera di avere la cache e la convalida del lato client se possibile, provare a salvare le chiamate sul server e inviare solo le differenze di dati, nel caso in cui la maggior parte della risposta per una richiesta con lo stesso parametro non cambi.
Ad esempio, al oVirt progetto open source chiediamo di ottenere le statistiche di una data macchina virtuale. alcuni dati della VM cambiano raramente, quindi inviamo solo MD5, se i dati cambiano anche il valore MD5 viene modificato, eseguiamo una richiesta per ottenere i dati completi, e non solo l'MD5.
Ho già menzionato l'ibernazione - ti consiglierei di considerare attentamente l'utilizzo di esso - se hai bisogno di eseguire molte scritture e meno letture, Hibernate potrebbe non essere l'ideale per te, e dovresti considerare di lavorare con Spring-JDBC come wrapper su JDBC.
Indicizza il tuo database con saggezza e usa uno schema db corretto. Prendi in considerazione l'utilizzo di un livello di stored procedure poiché sono precompilate e ottimizzate

Vorrei precisare che in passato mi sono occupato di un sistema (nodo singolo) su mysql (accesso di sola lettura) con jboss 4.2.1 e riuscito a raggiungere 2000 utenti simultanei
(non accedendo subito in termini di apertura 2000 socket contro il nostro server), ma utilizzando / navigando il nostro sistema, utilizzando JBoss Cache e precaricando alla cache alcuni dei dati più accessibili, oi dati che abbiamo realizzato saranno "caldi e popolari" ma la nostra soluzione è stata buona per la nostra architettura e i nostri flussi,
così come dico in questi casi -
Ci sono più suggerimenti e trucchi, ma in realtà dipende dalla tua architettura e dai flussi che devi avere nel tuo sistema. Buona fortuna!

    
risposta data 22.06.2012 - 08:09
fonte
3

Buona domanda. Probabilmente è difficile dire quale sia l'approccio migliore, ma proverò dalla mia esperienza.

Il modo migliore per ridimensionare l'applicazione web basata su Java è scriverlo come apolido possibile (se possibile). Ciò consente di ridimensionare orizzontalmente l'applicazione, in cui è possibile aggiungere server tomcat se vi sono più utenti simultanei.

Tuttavia, come hai notato, potrebbero esserci problemi con le connessioni al database. Ma la domanda che ho è, come stai ottenendo i dati? Viene generato dall'utente o si ottengono i dati da terze parti? Questo è molto importante perché, se offri un servizio al tuo utente con i dati aggregati da applicazioni di terze parti (ad esempio FB, Twitter, ecc.), Allora ciò che puoi seguire è scrivere nel database master e replicare i dati nei database slave che sono assegnati a ciascuna istanza di tomcat. Quindi ogni server tomcat può ottenere dal proprio database slave.

 Are there faster alternatives to Mysql?

Si può andare per il cluster MySQL che ha un archivio dati in memoria. Ma attenzione al fatto che l'applicazione potrebbe richiedere alcune modifiche. Il sql joins non è ben supportato nel cluster MySQL sebbene nell'ultima versione ci siano miglioramenti per lo stesso. Se il costo non è un fattore, allora puoi provare Oracle.

La soluzione di caching migliorerà sicuramente le prestazioni. Ma poi, tutto dipende dall'architettura dell'intera applicazione. Dovresti essere ben consapevole di quando spingere i dati nella cache, quando renderli sporchi (rimuovi dalla cache).

Per quanto riguarda la distribuzione del carico in ambiente multi server, ti suggerirei di utilizzare il bilanciamento del carico piuttosto che utilizzare Apache per il bilanciamento del carico.

    
risposta data 19.06.2012 - 08:49
fonte
2

Attualmente sto configurando un sistema simile (a livello professionale) e questo è il design che ho scelto:

  • Due loadbalancer Nginx (entrambi attivi, entrambi con failover per l'altro, bilanciati con DNS round robin)
  • Due database MySQL in modalità di replica master master
  • Due istanze di Tomcat come cluster tomcat
  • Due istanze Memcached per la memorizzazione nella cache e nella condivisione dello stato della sessione per il cluster Tomcat

Ciò consentirà una soluzione ridondante, ad alta disponibilità e scalabile.

I loadbalancers (su hardware decente) bilanciano facilmente una linea saturata di 1 gbit ciascuno. Questo è anche un ottimo posto per lo scaricamento di SSL.

Puoi salvare le informazioni sulla sessione in memcached. Nel caso in cui un'istanza di tomcat fallisca, un'altra istanza di tomcat può recuperare informazioni rilevanti sulla sessione e i client non noteranno nulla. Non dimenticare di combinare questo con sessioni appiccicose troppo. (Per mantenere il traffico di rete verso il basso)

Il clustering Tomcat ha anche un'opzione per condividere le informazioni sulla sessione tra il cluster in tempo reale, senza usare memcached. Anche se penso che le prestazioni siano sane, usare Memcached sarà migliore.

Se hai bisogno di più potenza in una di queste applicazioni:

  • Nginx: aggiungi più loadbalancer, anche se non credo che questo sarà il collo di bottiglia molto presto.
  • Tomcat: puoi facilmente aumentare le dimensioni del cluster Tomcat o aggiungere altri cluster
  • Mysql: aggiungi alcuni slave di sola lettura o aumenta la dimensione del cluster (a seconda dell'applicazione, ma dal momento che hai scritto un'applicazione basata su REST, questo non dovrebbe essere un problema)
  • Memcached: aggiungi altri nodi, Memcached scala piuttosto bene, credo.

Non so come sia costruita la tua applicazione e quali siano i grandi hog delle risorse, ma se vedi un carico elevato del database (durante i tuoi loadtest!), aggiungere una cache tra l'applicazione e il database potrebbe sicuramente migliorare notevolmente le prestazioni . Ma non dimenticare che non tutto è intercambiabile, se le tue domande sono sempre diverse, il caching non aiuta (molto)

Il mio consiglio è di scaricare VMware Workbench (o un similare software di virtualizzazione) e provare a creare una configurazione semplice. Nessun bilanciamento del carico o clustering, solo le basi e il lavoro da lì. Uno ad uno aggiunge più funzionalità (bilanciamento, memorizzazione nella cache, clustering, ecc.) E assicurati di fare qualche ricerca su ciascun argomento, così saprai che hai fatto la scelta giusta.

Se continui a eseguire gli stessi test delle prestazioni durante questo processo, puoi vedere da solo se usare X è meglio che usare Y nel tuo setup, o che impatto ha il caching avrà, ecc.

Alla fine, una configurazione come questa dipende molto dalle esigenze della tua applicazione e dei suoi clienti, tutto può essere fatto in vari modi, ognuno con i suoi punti di forza e di debolezza.

Altre domande?

Buona fortuna!

Wesley

    
risposta data 25.06.2012 - 18:47
fonte

Leggi altre domande sui tag