2012-08-07 22 views
9

Ho letto le diapositive di UberConf di quest'anno e uno degli oratori sta argomentando che Spring JMS aggiunge un sovraccarico prestazionale al sistema di code messaggi, tuttavia non vedo alcuna prova a supporto delle diapositive . Il relatore spiega anche che il point-to-point è più veloce del tradizionale metodo "publish-subscribe" perché ogni messaggio viene inviato una sola volta invece di essere trasmesso a tutti i consumatori.Messaggistica JMS ad alte prestazioni

Mi chiedo se nessun guru di messaggistica Java esperti possono pesare-in qui e chiarire alcuni aspetti tecnici:

  • C'è in realtà un sovraccarico di prestazioni dovute all'utilizzo di primavera JMS invece di solo JMS puri? Se sì, come e dove viene introdotto? C'è un modo per aggirarlo?
  • Quali prove effettive ci sono per supportare il P2P è più veloce del modello pub-sub, e in tal caso, ci sono mai casi in cui si vorrebbe pub-sub su P2P (ovvero perché andare più lentamente?!?)?

risposta

22

1) primaria, il sovraccarico di primavera JMS è il uso di JmsTemplate per inviare messaggi senza un meccanismo di memorizzazione nella cache sottostante.In sostanza, JmsTemplate farà quanto segue per ogni messaggio inviato:

  • Crea connessione
  • Crea sessione
  • Crea Produttore
  • Crea messaggio
  • Invia Messaggio
  • Chiudi sessione
  • Chiudi collegamento

Ciò potrebbe essere paragonato a scritti manualmente il codice in cui si riutilizza le cose:

  • Crea connessione
  • Crea sessione
  • Crea Produttore
  • Crea messaggio
  • Invia Messaggio
  • Crea messaggio
  • Invia messaggio
  • Crea messaggio
  • Invia Messaggio
  • Chiudi sessione
  • Chiudi connessione

Dal momento che la creazione di connessioni, sessioni e produttori ha bisogno di comunicazione tra il client e il provider JMS e, naturalmente, l'allocazione delle risorse, creerà un sovraccarico piuttosto ampio per molti piccoli messaggi.

È possibile aggirare il problema memorizzando nella cache le risorse JMS. Ad esempio, usa la molla CachingConnectionFactory o ActiveMQs PooledConnectionFactory (se stai usando ActiveMQ, con cui hai codificato questa domanda).

Se si esegue all'interno di un contenitore JavaEE completo, il pooling/caching è spesso incorporato e implicito quando si recupera il factory di connessione JNDI.

In fase di receving, utilizzando Spring Message Listening Container, c'è un sottile strato in primavera che potrebbe aggiungere poco overhead, ma gli aspetti primari è che è possibile modificare le prestazioni in termini di concorrenza ecc. This article lo spiega molto bene.

2)

PubSub è un modello di utilizzo, in cui l'editore non ha bisogno di sapere che gli abbonati che esiste. Non puoi semplicemente emularlo con p2p. E, senza alcuna prova a portata di mano, direi che se si desidera inviare un messaggio identico da un'applicazione a dieci altre applicazioni, una configurazione pub-sub sarebbe più veloce di inviare il messaggio dieci volte p2p.

D'altra parte, se si dispone di un solo produttore e un solo consumatore, scegliere il modello P2P con le code, poiché è più semplice da gestire in alcuni aspetti. P2P (code) consente il bilanciamento del carico, che pub/sub non (come facilmente).

ActiveMQ dispone anche di una versione ibrida, VirtualDestinations, che essenzialmente tratta gli argomenti con il bilanciamento del carico.

L'implementazione effettiva differisce da diversi fornitori, ma gli argomenti e le code non sono fondamentalmente diversi e devono comportarsi con prestazioni simili. Quello che invece dovresti controllare è:

  • Persistenza? (= più lento)
  • Selettori dei messaggi? (= più lento)
  • Concorrenza?
  • abbonati durevoli? (= Più lento)
  • richiesta/risposta, "sincrono" con code temporanee (= sovraccarico = più lento)
  • coda prefetching (rendimento = impatti in alcuni aspetti)
  • Caching
+2

Grande risposta, solo una piccola aggiunta agli argomenti vs code (si sta sorta di citarlo, ma sarebbe bene rendere esplicito). Gli argomenti garantiscono che ogni abbonamento duraturo o offline a un argomento riceverà un messaggio. Le code garantiscono che uno e un solo abbonato elaborino un messaggio. Oltre a ciò, gli argomenti possono essere utilizzati per la comunicazione 1-1 e le code possono avere più editori e utenti con bilanciamento del carico. È tuttavia necessario eseguire il bilanciamento del carico con argomenti semplici ed è inefficiente eseguire la distribuzione di eventi con le code. Cavalli per i corsi. – ddimitrov

+0

Buon punto, grazie per averlo chiarito. –

1

non sto MESSAGGISTICA guru, vorrei che non mi condividere il mio pensiero qui;)

  1. Ci sarà sempre in testa, perché avete indirezione supplementare. Anche se è semplicemente un livello extra nello stack di chiamate, è ancora in testa. Tuttavia, credo che un simile sovraccarico sia minimo. Puoi dare un'occhiata al codice sorgente di JmsTemplate. Non ci sono molte cose extra aggiunte da Spring durante l'invio. JmsTemplate sta facendo principalmente quello che devi fare se stai usando JMS comunque. Puoi sempre obiettare che quelle chiamate extra di controllo e di metodo più profonde richiedono sempre più ciclo e memoria della CPU. È vero, ma mi chiedo quanto sia significativo.

  2. PubSub e P2P (Argomento e coda nella terminologia JMS) sono solo due modelli diversi. Credo che non possano sostituirsi a vicenda. Non è possibile utilizzare il comando "invia una volta e trasmetti a più destinatari" utilizzando la coda e allo stesso tempo non è possibile avere il comportamento di consegna garantita quando si utilizza l'argomento (a meno che non si utilizzi l'abbonato duraturo, ma si tratta di un altro argomento). Quindi, scegliere il tipo giusto dipende da cosa si sta facendo, invece di dire ciecamente che il P2P è superiore rispetto PubSub (che credo sia non-senso)

2

1) modelli di primavera aprire/chiudere connessioni/sessioni per ogni messaggio inviato/ricevuto. Ecco perché è più lento. La maggior parte delle implementazioni JMS ha prestazioni migliori quando le connessioni/sessione rimangono aperte in modo che possano utilizzare ottimizzazioni come la prelettura dei messaggi, per non parlare dell'eliminazione del sovraccarico di eseguire tutti i bit di impostazione/eliminazione della connessione.

2) Gli argomenti sono generalmente più lenti se si stanno copiando/replicando i dati su più di un consumatore. Questa è solo una questione di fisica. Se 10 mega di messaggi vengono inviati in coda a una coda, è necessario trasmettere ai consumatori solo 10 mega di dati. Mentre sei in argomento, se hai 10 consumatori e invii 10 mega di dati, allora 100 mega di dati devono essere trasmessi ai consumatori. Pertanto, per la maggior parte delle implementazioni JMS:

  • l'aggiunta di un utente a un argomento può solo rallentare il tasso di consumo.
  • L'aggiunta di un utente a una coda di solito contribuisce ad aumentare la velocità di eliminazione.
+0

Riguardo alla velocità della coda di argomenti e di coda. Sono due diversi casi d'uso che si stanno confrontando e che non sono realmente comparabili, o si desidera che tutti i dati vengano inviati a tutti i consumatori o solo a uno solo. In ogni caso, la tua risposta è, ovviamente, corretta. –

3

Stai parlando delle diapositive di Mark Richards? Ha pubblicato il codice sorgente per i suoi benchmark, quindi puoi testare la sua affermazione sulle prestazioni di JmsTemplate. Il suo codice di riferimento utilizza Spring's CachingConnectionFactory, e nonostante la memorizzazione nella cache dimostra ancora una significativa penalizzazione delle prestazioni con JmsTemplate. Ho eseguito, profilato e analizzato il suo codice. La risposta breve è che il sovraccarico di JmsTemplate è trascurabile e la disparità misurabile delle prestazioni nel suo codice ha a che fare con le modalità di invio asincrono vs sincronizzazione di ActiveMQ. Ho postato la mia analisi qui:

JmsTemplate is not evil

Problemi correlati