J'ai une application utilisant le planificateur de quartz pour planifier des travaux. L'application exécute actuellement la version 1.6.2 de quartz. Mon jobstore est org.quartz.impl.jdbcjobstore.jobstoretx avec une base de données Oracle le sauvegarde. Le clustering est activé, mais il n'y a qu'un seul planificateur à l'aide de la base de données. Mon quartz Threadpool est configuré comme suit:
2011-05-20 04:09:30,097 INFO [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName1 misfired job DEFAULT.DEFAULT at: 04:09:30 05/20/2011. Should have fired at: 04:08:29 05/20/2011 2011-05-20 04:09:30,120 INFO [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName1 misfired job DEFAULT.DEFAULT at: 04:09:30 05/20/2011. Should have fired at: 04:09:30 05/20/2011 2011-05-20 04:09:30,125 INFO [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName2 misfired job DEFAULT.DEFAULT at: 04:09:30 05/20/2011. Should have fired at: 04:08:30 05/20/2011 2011-05-20 04:09:30,138 INFO [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName2 misfired job DEFAULT.DEFAULT at: 04:09:30 05/20/2011. Should have fired at: 04:09:30 05/20/2011 2011-05-20 04:11:29,998 INFO [QuartzScheduler_scheduler-servername-111305822376676_MisfireHandler] o.q.impl.jdbcjobstore.JobStoreTX - Handling 2 trigger(s) that missed their scheduled fire-time.
4 Réponses :
En regardant le quartz piscine de thread , il utilise une boucle d'attente () / notify (), qui n'est pas juste, et sélectionnera au hasard un nouveau fil lorsque plusieurs threads attendent. P>
Vous pouvez utiliser votre propre instance de threadpool qui est juste. Copiez le code de SimplethreadPool, mais remplacez le verrouillage autour de Nextrunnablelock avec un Java.Util.RetrantRantlock, en passant fidèle au constructeur équitable. Dans votre taille modifiée, utilisez retrantRantlock.lock (block () / Déverrouillage () au lieu de synchronisé et utilisez reentrantlock.Newconition (). Signal () / Await () au lieu d'attendre / notifier votre problème, et cela pourrait résoudre votre problème. P >
Ces threads dans la piscine n'ont pas d'emplois qui leur sont attribués, alors l'équité dont vous parlez n'a pas d'importance. Le fait de ces threads est libre d'abord, dirigera le prochain travail.
Je pense que l'équité provient de fils à l'extérieur de la piscine de fil, de runinthread et de blockforavailhareads qui attendent injustement. Qu'avez-vous voulu dire quand vous avez dit: "Quand ma piscine de fil est maximale"
RunintHread () et BlockforavailBethreads () sont tous deux appelés à partir du même thread - il n'y a pas de threads multiples en attente de l'issue de ces méthodes, de sorte que la «équité» d'attente () / notifier () n'a pas d'importance. (Seulement un service de fil / utilise le pool de threads).
J'ai modifié la question un peu pour fournir plus d'informations. Par "ma piscine de thread est maximum" Je veux dire que le quartz threadpool est sorti des threads de travailleur pour exécuter des emplois, ce qui a entraîné des tâches nouvellement déclenchées pour se rendre.
Je sonne comme si vous courez dans un scénario de raffinage (un scénario où il y a plus d'emplois prêts à être exécutés que des threads ouvrières). Définissez la propriété des instructions et / ou prioritaires sur les déclencheurs pour modifier la manière dont chacun se comporte après avoir passé son temps de feu. P>
En outre, vous pouvez également envisager d'augmenter le seuil de rachetage, ce qui changerait la quantité de temps qu'un déclencheur peut être «tard» en attente d'un fil d'exécution avant qu'il ne soit considéré comme un raté (et que son instruction a été appliquée à celle-ci) . P>
est-il possible de faire mes travaux d'attente (inscriffés) pour être tiré dans l'ordre dans lequel ils ont été déclenchés une fois que l'espace dans la threadpool de quartz devient disponible? p> blockQuote>
Les instructions "Ne rien faire" laisseront les temps d'incendie comme. p>
C'est certainement un scénario à un raté - j'ai mis à jour la question pour être un peu plus spécifique sur ce point. Y a-t-il une instruction de raie qui rendrait les emplois rats pour être ramassés dans l'ordre d'avoir été licenciés à l'origine?
Le javadoc pour le misfire_instrucance_do_nothing radefire se lit comme suit: "Indique le planificateur que sur une situation mal incendie, le crontrigger souhaite avoir son prochain feu à jour à la prochaine fois dans le calendrier après l'heure actuelle, mais ce n'est pas vouloir être viré maintenant. " Peut-être que je me méprie, mais cela me semble que le travail ne ferait que sauter le tir et ne rien faire avant la prochaine fois qu'il est déclenché. Ce n'est pas ce que je veux. Je souhaite que le travail fonctionne dès qu'il y a des threads disponibles, mais avec les travaux d'attente les plus longs en attendant d'abord s'il existe plusieurs emplois désfineurs.
Dans le cas d'un Si plusieurs tâches sont malfiées, plusieurs d'entre elles peuvent être reprogrammées en même temps (même milliseconde), car l'ordinateur fonctionne rapidement. P>
En conséquence, et si aucune priorité n'est définie, le planificateur décrochera la première tâche suivante, tout avec le même crontrigger code>, la méthode
updadiafeafire () code> peut réorganiser la tâche à
nouvelle date () code> case
MISFIRE_INSTRACTION_FIRE_ONCE_NOW CODE> POLITIQUE. P>
NextFireTime code>, en fonction de la touche ou du nom complet. P>
updadiafetermisfisire () code> doit avoir ré-planifier la tâche à une date unique
code> à l'aide d'un fichier
thread.sleep (25) code>, en tant que Exemple. P>
Lorsque QUARTZ gère un déclencheur qui a manqué son temps de feu, il mettra à jour le Je suggérerais d'augmenter le NextfireTime code> de la gâchette. Par défaut, une gâchette sera considérée comme manquée si elle est NextFireTime est supérieure à 60 secondes dans le passé. Les déclencheurs manqués devraient toujours être sélectionnés sur la base de la prochaine commande et de la priorité, mais je suppose qu'il semble aléatoire car certains déclencheurs ont été mis à jour et d'autres n'ont pas. P>
org.quartz.jobstore.misfiReShold code> propriété. Voir http://www.quartz-schéduler.org /Documentation/Quartz-2.x/configuration/configramjobstore.html (bien que la propriété soit identique à tous les travaux Jobstores). Cela devrait le rendre moins probable que vos déclencheurs soient rétablis. P>
Je ne peux pas vraiment tester cela parce que j'ai eu un nouvel emploi, je n'ai pas utilisé de quartz depuis des années et que je ne peux pas être dérangé pour mettre en place un projet de test uniquement pour voir si cela fonctionne. Cependant, je suis impressionné que vous ayez la peine de répondre à une question de 5 ans et de votre réponse semble utile, alors je vais aller de l'avant et marquer cela comme résolu :)
J'avais un problème similaire afin de rechercher un débordement de pile. En fin de compte, j'ai creusé le code et j'ai compris moi-même mais je pensais que je laisserais cela ici au cas où quelqu'un d'autre cherchait la réponse à l'avenir.
@Jonquarfoth Qu'est-ce qui a fonctionné pour vous à la fin? Je suis en train de programmer des milliers de milliers d'emplois et de travail sera longuement courir car je dois migrer BLOB de l'emplacement vers un autre et que ces blobs peuvent être aussi gros que 100 Go. Je prévois d'utiliser le clustering Quartz afin que, lorsque le maître planifie l'emploi, les esclaves continueront de travailler sur ces emplois et je ne me soucie pas vraiment de Mlle Fire depuis que je me soucie juste de l'emploi de l'un des esclaves à la fin. . Peut-être que je peux définir une valeur de seuil ridiculement importante. S'il vous plaît laissez-moi savoir ce que vous en pensez. Merci.