Scrivere un sistema di accodamento di base è abbastanza semplice, ma come hai notato sopra con tutte le sfide, farlo nel modo giusto è un'altra cosa. Ho usato sistemi cresciuti in casa per i quali ho scritto il codice sorgente, sistemi di terze parti e vari provider JMS. JMS (Java Messaging Service) è di gran lunga la soluzione più completa che abbia mai incontrato finora. Gran parte di ciò che chiedi è disponibile in JMS. Il mio provider JMS preferito è ActiveMQ. Gratuito, performante, facile da installare e, soprattutto, facile da integrare nella mia app con Spring. I provider JMS non forniscono tutto ciò che è stato richiesto immediatamente, ma forniscono una serie di strumenti per gestire gran parte di ciò che è stato richiesto in caso di necessità dell'applicazione. Non ho trovato molte applicazioni che richiedono tutto ciò che hai elencato. L'ordinamento potrebbe non essere importante (è meglio se non lo è),
http://activemq.apache.org/what-open-source-integration-solution-works-best-with-activemq-.html
Ha ordini forti o persi? Sì. Ha entrambi a seconda delle esigenze dei programmi. Ecco i dettagli: http://activemq.apache.org/total-ordering.html .
Ha messo idempotente? No, ma questo è banale da implementare nel livello dell'applicazione se ne hai bisogno.
Possiamo avere più code di quelle che possono stare su una singola macchina? Sì. Puoi avere server in cluster e, se volevi configurare più macchine con code diverse, puoi farlo da entrambi.
Possiamo avere più dati in una coda di quelli che possono stare su una singola macchina? Sì, la maggior parte dei provider JMS deve utilizzare una sorta di DB / archiviazione persistente per garantire che i messaggi non vengano eliminati o persi se il provider JMS non funziona.
Quante macchine possono arrestarsi in modo anomalo prima di perdere potenzialmente i dati? È un po 'più difficile rispondere perché è legato al tempo. Tuttavia, è possibile arrestare in modo anomalo un provider JMS e, a condizione che il disco non sia danneggiato, tornerà indietro e inizierà dove ha ricevuto l'ultimo commit. Ciò significa che i messaggi potrebbero essere recapitati due volte, ma se si codifica l'app per gestirla non è un problema. Finché avrai almeno uno di ogni tipo (produttori, consumatori o server JMS) verrà completato. È inoltre possibile avere carico / bilanciamento / failover per ridondanza se un disco si spegne.
Può tollerare divisioni nette? Penso di aver capito cosa intendi per "net-split", ma non ne sono del tutto sicuro. Immagino che tu intenda se i server JMS sono raggruppati e perdendo la connessione con uno dei server si passerà a un altro server e riprenderà da dove era stato interrotto. Sì, ma ancora una volta questi tipi di situazioni possono portare a messaggi duplicati a seconda del punto in cui il client ha perso la connessione.
Può riconciliare automaticamente i dati quando viene risolta una divisione in rete? Se si utilizzano sessioni trattate, verrà riconsegnato qualsiasi messaggio a cui è stato richiesto un commit su client esistenti che sono attivi.
Può garantire la consegna quando i clienti possono andare in crash? Sì, questo è uno degli obiettivi principali di JMS. La consegna garantita significa che se un messaggio è in coda, è garantito che sia gestito da un cliente.
Può garantire che lo stesso messaggio non venga recapitato più di una volta? Sì se vengono utilizzate le sessioni eseguite. Ciò significa che un client ha accettato il messaggio e chiamato commit / rollback. Una volta chiamato, il commit non riconsegna il messaggio.
Un nodo può bloccarsi in un dato punto, tornare indietro e non inviare spazzatura? Nel caso in cui si disponga di code cluster durevoli. Sì, non verrà generato "junk" se l'altro nodo nel cluster ha recapitato il messaggio. Può comunque riconsegnare tutto ciò che non è stato riconosciuto.
È possibile aggiungere nodi o rimuovere nodi da un cluster in esecuzione senza tempi di inattività? Sì.
È possibile aggiornare i nodi in un cluster in esecuzione senza tempi di inattività? È un po 'più complicato per me rispondere, ma credo che sì, puoi farlo.
Può funzionare senza problemi su server eterogenei? Cosa significa esattamente? Ho scoperto che la maggior parte dei provider JMS sono molto facili da eseguire in ambienti che utilizzano hardware, sistema operativo diversi, ecc. Anche se, se intendi prestazioni, è un'altra cosa. Qualsiasi sistema di elaborazione distribuito può essere influenzato negativamente da un nodo lento. Avevo 2 server Intel 8 Core che eseguivano la coda e i consumatori. Sono 16 core insieme e ho ottenuto prestazioni migliori utilizzando solo quelle due scatole rispetto a quando ho aggiunto una macchina single core come consumatore. Quella macchina single core era molto più lenta che ha rallentato l'intera griglia di un fattore 2x. Questo non aveva nulla a che fare con JMS di per sé.
Riesci a "incollare" le code a un gruppo di server? Risposta breve sì. Mi viene in mente un modo in cui è possibile eseguire un cluster che si trova solo nel data center europeo e configurare lì la coda. Quindi, nella configurazione di primavera, imposta i tuoi consumatori per consumare quella coda e altre code su altri cluster. Potresti voler consultare i documenti:
http://activemq.apache.org/clustering.html
Può assicurarsi di inserire repliche di dati in almeno due datacenter, se disponibili? Ancora una volta lo credo, ma è meglio consultare i documenti del clustering.
Ancora una volta JMS ha molte opzioni che puoi modificare secondo le tue esigenze. L'uso di sessioni transitate e code durature comporta un costo in termini di prestazioni. Ho visto accendere tutte le campane e fischietti influire sulle prestazioni fino a 10 volte. Quando ho usato JBossMQ se avessimo disattivato alcune di queste funzionalità, abbiamo potuto ricevere circa 10.000 messaggi / s, ma attivandoli ci siamo ridotti a 1000 messaggi / s. Grande calo.