使用Vertx处理结果组-如何协调?

时间:2019-09-18 17:27:58

标签: vert.x vertx-verticle

我有一个工作处理系统,其中每个工作包含数千个需要不同策略才能完成的任务。单个任务构成了整个工作。如果所有任务均已完成,则将作业标记为已成功完成,并执行其他步骤;如果任何任务失败,则必须将作业标记为已失败,并执行其他步骤(如果作业超时,则必须标记作业)失败并采取其他措施。

一旦收到作业的所有结果,就可以提取下一个作业。当前正在处理作业时,不应提取下一个作业。

这是流程的样子:

enter image description here

Job Polling Verticle将作业发布到事件总线,而Job Processing Verticle将每个任务发布到事件总线。作业策略完成后,它将任务结果发布到事件总线。

问题是我不知道确定该模型中所有任务何时完成的正确方法。所有的顶点都是无状态的,“作业处理顶点”不等待任何将来,即使“作业结果顶点”是有状态的,它也不知道应该期望多少结果。

我能想到的唯一方法是拥有一个全局有状态对象。但是我认为这不是一个好的设计。

enter image description here

此外,我需要知道作业何时超时。也就是说,它的运行时间比预期的要长,我需要考虑它的失败,记录并继续前进。

我可以使用全局状态来做到这一点,但我再次认为这不是正确的解决方案。

这种垂直图案对我想做的事情有意义吗?

1 个答案:

答案 0 :(得分:3)

首先,让我尝试解决您的问题。然后,我将尝试解释该设计存在哪些问题。

  

问题是我不知道确定此模型中所有任务何时完成的正确方法。所有的顶点都是无状态的,“作业处理顶点”不等待任何将来,即使“作业结果顶点”是有状态的,它也不知道应该期望多少结果。

解决方案可以是参考计数顶点。每个工作程序在启动时应在事件总线上发出start message,并在事件总线上发出jobId,在完成时应发出end message的{​​{1}}。即使您有扇出(那些情况是您不知道有多少工人),计数verticle也会知道这一点。在您的图表中,“作业后期处理顶点”是一个很好的选择。它可以维护一个计数器,只有当它达到零时,它才应该开始下一个作业。这也有助于避免实际共享一些内存引用。

  

此外,我需要知道作业何时超时。也就是说,它的运行时间比预期的要长,我需要考虑它的失败,记录并继续前进。

在相同的垂直版本中,每次获得新的jobId时都可以启动一个计时器。如果得到start message,请取消计时器。否则,取消当前作业,然后重新开始。

现在,此解决方案可以使用,但是设计存在两个主要缺陷。看来,事实之一是您将所有流量保持在内存中。如果您的应用程序崩溃,所有进度都将丢失,并且不清楚如何记录。也许轮询数据库中的end message表实际上会更好,因为无论如何您的作业执行都是顺序的。

第二点是所有这些超时和引用计数都是结构化并发的自制实现。也许您应该为此考虑一下类似Kotlin的协程,它将为您解决许多问题。