Bonne façon d'utiliser les EJB méthodes Asynchrones
J'ai deux tâches que je dois accomplir dire task1
et task2
qui font partie du même processus d'affaires. Je dois donner une réponse pour l'utilisateur final au moment de task1
termine il est donc temps de réponse doivent être réduites au minimum.
Mon approche actuelle consiste à effectuer task1
et dès que task1
est fini, invoquer task2
méthode asynchrone. task2
est compliqué et il est temps de réponse est hors de mon contrôle, car elle a une certaine dépendance externe.
@Stateless
public class SessionBean1 {
@Inject
SessionBean2 sessionBean2;
public void doTask1(){
//task one stuff
sessionBean2.doTask2();
}
}
@Stateless
public class SessionBean2 {
@Asynchronous
public void doTask2(){
//do task2 stuff
}
}
Dans websphere 8.0 (le conteneur d'EJB) les méthodes synchrones et asynchrones méthodes sont exécutées par les différents pools de threads.
Mon hypothèse de départ était que, même si task2
effectue mal, task1
aurait pas d'impact, mais malheureusement ce n'est pas vrai.
Si task2
effectue mal, tous les threads thread asynchrone piscine sera occupée. Ce sera la cause de task1
à attendre pour les threads asynchrones pour être libre et donc task1
a de l'impact.
Le message dans websphrere journaux de serveur :
The request buffer for thread pool WorkManager.WebSphere_EJB_Container_AsynchMethods_Internal_WorkManager has reached its capacity
Ma question est ce que serait une bonne façon de réaliser ce que je suis en train de réaliser ici.
Comme dans les liens image, le pas de méthode async les demandes sont limitées et dépendent du nombre de async threads. Je peux augmenter le pas de fils, mais même si, pour quelques minutes task2 effectue mal, mon task1 devra encore attendre. Aussi le non de threads sont limitées par la configuration du matériel.
L'idée d'utiliser une file d'attente JMS suggéré par @rjdkolb est une bien meilleure idée de la taille du pool de threads est problématique.
Actuellement, je suis en ajoutant les paramètres de la méthode pour
task2
à un ConcurrentLinkedQueue et puis d'interrogation et d'appeler la méthode task2
périodiquement à l'aide d'un Timer. Jusqu'à présent, il s'est avéré être la bonne. À l'aide de JMS peut-être trop à la fois comme task1
et task2
sont sur le même serveur.Tous Java EE implémentations ont JMS "intégrée" et, par conséquent, peuvent s'exécuter dans le "même serveur".
OriginalL'auteur ares | 2016-01-13
Vous devez vous connecter pour publier un commentaire.
Une autre alternative serait d'augmenter la "demande de Travail taille de file d'attente" de la "EJB asynchrone de la méthode d'invocation de paramètres" dans la Console d'administration. C'est une file d'attente, avant le pool de thread lui-même, donc cela peut vous acheter un peu plus de temps.
Idéalement, ce devrait être utilisé en combinaison avec les délais suggérés ci-dessus.
The runtime currently uses the larger of 20 and the value of maximum number of threads.
fait du sens?En regardant votre image, je prends ça comme "le plus grand de 15 ou 20", donc dans votre cas, il devrait être de 20. Vous pouvez garder le maximum de 15 thread-la taille du pool, et d'augmenter votre file d'attente de quelque chose de beaucoup plus grand. J'avais j'espère la file d'attente devraient avoir une petite mémoire/processeur d'empreinte, de sorte qu'il puisse stocker vos demandes en attente pour task2, tout en laissant ceux existants terminer et de le garder au sein de votre limite de matériel. Mais si le task2s peut prendre une durée indéterminée à la fin, puis je pense que les délais d'attente serait la voie à suivre
OriginalL'auteur matt freake
Je pense que @AccessTimeout est ce que vous cherchez. - Je voir un exemple ici
Cela permettra de limiter la quantité de temps que .doTask2() permet d'exécuter et d'éviter à votre problème.
SessionBean2
Comme une alternative :
De limiter le temps de l'async processus peut prendre, utiliser la poignée.get(xx, TimeUnit.xx); la méthode. Vous aurez également besoin de retourner Avenir et pas seulement nulle pour le faire fonctionner.
J'espère que cela convient à votre cas d'utilisation que vous aurez besoin de faire appel un .obtenir
SessionBean2
Si vous voulez qu'il soit asynchrone et toujours de la course, au lieu de mettre un message d'une file d'attente JMS
...ou l'utilisation d'un EJB de la minuterie, ce qui est probablement le plus facile à utiliser.
OriginalL'auteur rjdkolb