J'ai effectué un traitement séquentiel de messages dans une grappe sur une très grande échelle - 1,5 million + message/jour, en utilisant une combinaison du modèle des consommateurs concurrents et un modèle de bail.
Voici le kicker, cependant - votre exigence que vous ne pouvez traiter qu'un trans à la fois va vous empêcher d'atteindre vos objectifs. Nous avions la même exigence de base - les messages devaient être traités dans l'ordre. Au moins, nous avons pensé que nous l'avons fait. Puis nous avons eu une révélation - comme nous avons réfléchi au problème, nous nous sommes rendu compte que nous n'avions pas besoin d'un ordre total. Nous avons réellement besoin de commander seulement dans chaque compte. Par conséquent, nous pourrions répartir la charge entre les serveurs d'un cluster en affectant des plages de comptes à différents serveurs du cluster. Ensuite, chaque serveur était responsable de traiter les messages d'un compte donné dans l'ordre.
Voici la deuxième partie intelligente: nous avons utilisé un modèle de bail pour assigner dynamiquement des plages de compte à divers serveurs du cluster. Si un serveur de la grappe tombait en panne, un autre prenait le contrat de location et prenait la responsabilité du premier serveur.
Cela a fonctionné pour nous, et le processus a vécu dans la production pendant environ 4 ans avant d'être remplacé en raison d'une fusion d'entreprise.
Edit:
J'explique cette solution plus en détail ici: http://coders-log.blogspot.com/2008/12/favorite-projects-series-installment-2.html
Edit:
D'accord, Gotcha. Vous effectuez déjà le traitement au niveau dont vous avez besoin, mais comme vous êtes déployé sur un cluster, vous devez vous assurer qu'une seule instance de votre MDB extrait activement les messages de la file d'attente. De plus, vous avez besoin de la solution la plus simple possible.
Vous n'avez pas besoin d'abandonner votre mécanisme MDB que vous avez maintenant, je ne pense pas. Essentiellement, ce dont nous parlons ici est une exigence pour un mécanisme de verrouillage distribué, pas pour mettre une phrase trop chic.
Alors, laissez-moi suggérer cela. Au point où votre MDB s'inscrit pour recevoir des messages de la file d'attente, il devrait vérifier le verrou distribué, et voir s'il peut le saisir. Le premier MDB à saisir le verrou gagne, et seulement il enregistrera pour recevoir des messages. Donc, maintenant vous avez votre sérialisation. Quelle forme doit prendre ce verrou? Il y a beaucoup de possibilités. Eh bien, qu'en penses-tu? Si vous avez accès à une base de données, son verrouillage transactionnel fournit déjà une partie de ce dont vous avez besoin. Créez une table avec une seule ligne. Dans la rangée est l'identifiant du serveur qui détient actuellement le verrou, et un délai d'expiration. C'est le bail du serveur. Chaque serveur doit avoir un moyen de générer son identifiant unique, par exemple le nom du serveur plus un identifiant de thread.
Si un serveur peut obtenir un accès de mise à jour à la ligne et que le bail a expiré, il doit le récupérer. Sinon, il abandonne. S'il saisit le bail, il doit mettre à jour la ligne avec une heure dans un proche avenir, comme cinq minutes environ, et valider la mise à jour. Le serveur actif doit mettre à jour le bail avant son expiration. Je recommande de le mettre à jour quand il reste la moitié du temps, donc toutes les 2-1/2 minutes si le bail expire dans cinq. Avec ceci, vous avez maintenant le basculement. Si le MDB actif meurt, un autre MDB (et un seul) prendra le relais.
Cela devrait être assez simple, je pense. Maintenant, vous voulez que les MDB dormantes vérifient le verrou de temps en temps pour voir si elle est libérée. Ainsi, les MDB actifs et les MDB dormants doivent tous faire quelque chose périodiquement. Vous pourriez les faire apparaître un fil séparé pour le faire. De nombreux fournisseurs de moteurs d'applications ne seront pas heureux si vous faites cela, mais ajouter un thread n'est pas un gros problème, d'autant plus qu'il passe le plus clair de son temps à dormir. Une autre option serait de lier dans le mécanisme de minuterie que de nombreux moteurs fournissent, et le faire réveiller votre MDB périodiquement pour vérifier le bail. Oh, et en passant - assurez-vous que les administrateurs du serveur emploient NTP pour garder les horloges raisonnablement synchronisées.
Les gars, merci pour vos idées sur le design. Je vous assure que le design est correct. L'objectif principal de l'application n'est pas de traiter les messages jms, la file d'attente est uniquement là pour traiter les tâches qui peuvent être effectuées en arrière-plan et ne nécessitent pas beaucoup de performances. L'exigence pour ces messages est qu'ils doivent être traités dans l'ordre dans lequel ils ont été placés, et ils ne doivent pas non plus être traités en parallèle, sinon il se produira. La question est, existe-t-il un moyen facile de configurer une application j2ee s'exécutant sur un cluster pour n'avoir qu'un seul mdb actif? –
Bien sûr, vous pouvez utiliser le mécanisme de bail que j'ai décrit avec un bail unique. c'est vraiment facile, surtout s'il y a déjà une base de données quelque part. –
Alors, quel est le niveau de débit dont vous avez besoin?combien de messages/seconde, par exemple? –