java 使用 Quartz 在多个无状态应用服务器上调度单个作业
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6663182/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using Quartz to Schedule Single Job Across Multiple Stateless App Servers
提问by Scruffers
I have a layer of identical app servers behind a load balancer. For operational reasons I have the constraint that the application configuration on both app servers must be identical so that nodes can easily be added and removed. All app servers share the same database. App servers are not/will not be clustered.
我在负载均衡器后面有一层相同的应用程序服务器。出于操作原因,我有一个限制,即两个应用程序服务器上的应用程序配置必须相同,以便可以轻松添加和删除节点。所有应用服务器共享同一个数据库。应用服务器不会/不会被集群。
This has worked fine until now, but now I would like to have a scheduled job that executes on exactly one of the app servers. All app servers will run Quartz and have the same schedule for running jobs. The trigger will fire on every app server, but I would like only one app server to actually execute the job - essentially they all race to start and only one actually starts, the remaining app servers just ignore the job. The idea here is that if we lose an app server, another one would run the job instead, and if we add new app servers, they will take their turn at running jobs.
到目前为止,这一直工作正常,但现在我想要一个在其中一个应用服务器上执行的预定作业。所有应用服务器都将运行 Quartz 并具有相同的作业运行时间表。触发器将在每个应用程序服务器上触发,但我希望只有一个应用程序服务器实际执行该作业 - 基本上它们都争先恐后地启动并且只有一个实际启动,其余的应用程序服务器只是忽略该作业。这里的想法是,如果我们失去一个应用程序服务器,另一个将运行该作业,如果我们添加新的应用程序服务器,它们将轮流运行作业。
I was planning to do this by having a 'job lock' table in the database that all app servers would read prior to starting a job and only start if job is 'unlocked'. The app server that makes the update first to the table will essentially block others by updating the table to a running state/resetting it at the end of the job.
我计划通过在数据库中有一个“作业锁定”表来实现这一点,所有应用程序服务器都会在开始作业之前读取该表,并且只有在作业“解锁”时才启动。首先对表进行更新的应用程序服务器将通过将表更新为运行状态/在作业结束时将其重置来阻止其他应用程序服务器。
Before I build this, I'd appreciate some input from those with more experience of Quartz:
在我构建这个之前,我会感谢那些有更多 Quartz 经验的人的一些意见:
a) Can I hook this behaviour into Quartz so that it doesn't have to be done on a per job basis? I.e. developers can add new jobs without worrying about job locking as it is abstracted away.
a) 我可以将此行为挂钩到 Quartz 中,以便不必在每个工作的基础上完成吗?即开发人员可以添加新作业而无需担心作业锁定,因为它被抽象掉了。
b) Does Quartz provide any built in mechanisms to achieve something similar to above so I don't have to roll it myself?
b) Quartz 是否提供任何内置机制来实现与上述类似的功能,因此我不必自己滚动它?
Thanks!
谢谢!
回答by Sap
Do you think this will work for you? http://www.quartz-scheduler.org/documentation/quartz-2.3.0/configuration/ConfigJDBCJobStoreClustering.htmlExcerpt from the link
你认为这对你有用吗? http://www.quartz-scheduler.org/documentation/quartz-2.3.0/configuration/ConfigJDBCJobStoreClustering.html摘自链接
Clustering currently only works with the JDBC-Jobstore (JobStoreTX or JobStoreCMT), and essentially works by having each node of the cluster share the same database.
Load-balancing occurs automatically, with each node of the cluster firing jobs as quickly as it can. When a trigger's firing time occurs, the first node to acquire it (by placing a lock on it) is the node that will fire it.`
集群目前仅适用于 JDBC-Jobstore(JobStoreTX 或 JobStoreCMT),并且本质上通过让集群的每个节点共享相同的数据库来工作。
负载平衡会自动发生,集群的每个节点都尽可能快地触发作业。当触发器的触发时间发生时,第一个获取它的节点(通过在其上放置锁)是将触发它的节点。