石英弹簧设计建议

时间:2016-12-26 12:40:06

标签: spring quartz-scheduler

我在集群环境中使用石英+弹簧运行的作业很少。这些作业未设置为在集群环境中运行,因此每个作业将根据我们拥有的实例数运行多次。这些作业在AWS环境中运行。所以我们不确定会运行多少个实例,因为我们可以动态增加或减少。所以我们正在重构代码。

问题,让我们举例说明根据某些活动向用户发送电子邮件的工作。可能每天有1000个用户需要发送电子邮件。

目前,由于未设置为在群集环境中运行,因此每个实例都会运行作业并向用户发送有关其活动的电子邮件。因此,如果我有3个实例正在运行,则作业将运行3次,同一封电子邮件将发送给用户3次。

我们决定使用quartz jdbc来确保作业只运行一次。

我正在寻找关于如何在下面部分做的建议。

让我说我必须向300个用户发送电子邮件,而不是在1个实例上运行的工作选择用户并向300个用户发送电子邮件,我希望在任何实例上工作以从DB获得300个用户以及之后在其他用户上执行相同的工作实例也参与处理这300个用户。什么是最好的方式来做到这一点。我不想将这300个用户存储在临时表中,而是从数据库中挑选作业。有没有办法可以将这300个用户存储在全局内存中,例如memcached,并在那里从不同的实例中挑选数据(处理用户时的负载平衡)。我不想使用memcache,所以任何其他可用的选项或最好的方式我可以继续设计。

1 个答案:

答案 0 :(得分:0)

几个月前我们遇到了同样的问题。我们修复此问题,创建一个名为job的表,如下所示,仅用于控制正在运行的调度程序。

+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| id        | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| createdAt | datetime     | NO   |     | NULL    |                |
| updatedAt | datetime     | NO   |     | NULL    |                |
| version   | int(11)      | YES  |     | NULL    |                |
| running   | tinyint(4)   | YES  |     | NULL    |                |
| scheduler | varchar(255) | YES  | UNI | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+

基本上是启动调度程序集'运行'属性为1(正在运行),当完成设置为0(停止)时。

这种方法存在问题:

  • 每个调度程序都有相同的代码串来验证表(冗余代码)。
  • 如果您忘记了这一组,则调度程序无法正常工作。

不是最好的解决方案,但有了姑息效果。