2

在我的环境中,我需要安排长时间运行的任务。我有应用程序 A,它只向客户端显示当前正在运行的任务列表并允许安排新任务。还有应用程序 B 进行实际的艰苦工作。

所以应用 A 需要在应用 B 中调度一个任务。它们唯一的共同点就是数据库。最简单的做法似乎是添加一个包含任务列表的表,并让应用程序 B 每隔一段时间查询该表并执行新计划的任务。

然而,这似乎不是正确的做法。乍一看,企业环境中的工作工具似乎是消息队列。应用 A 向队列发送带有任务描述的消息,应用 B 从队列中读取消息并执行任务。在这种情况下,应用程序 A 是否有可能在不创建像上面提到的那样的表的情况下获取所有已调度任务的状态(持久队列?),应用程序 B 会将已完成任务的状态写入该表?另请注意,应用程序 A 可能有多个实例,并且每个实例都需要了解所有实例的所有任务。

“表格方法”的缺点是我需要进行数据库轮询。

“消息队列方法”的缺点是我在基础设施中引入了一个新的通信通道(另一件事可能会失败)。

你怎么看?还有其他想法吗?提前感谢您的任何建议:)

========== 更新 ==========

最终我决定采用以下方法:这个问题有两个方面:一个是 A 和 B 之间的通信。另一个是获取有关任务的信息。

对于通信来说,适合这项工作的工具是 JMS。为了获取数据,正确的工具是数据库。所以我会让应用程序 A 在“任务”表中添加一个新行来描述一个任务(我可以稍后查询这个表以获取所有任务的列表)。然后 A 将通过 JMS 向 B 发送一条消息,只是说“你有工作要做”。B 将完成工作并更新表中的任务状态。

感谢您的所有回复!

4

4 回答 4

2

您需要考虑现在的部署环境以及未来可能发生的变化。

您正在有效地研究两个问题,这两个问题都可以通过多种方式解决,具体取决于您能够获得多少基础设施并且愿意引入多少基础设施,但为您的问题“正确调整”设计也很重要。

虽然考虑使用数据库和消息传递是正确的,但您需要考虑这些项目是否对您的域来说是多余的,只有您和了解您的域的其他人才能真正回答这个问题。

我的建议是查看您所在地区已经使用的内容。如果您已经拥有可以构建的数据库基础架构,那么在数据库中监视任务活动和调度作业并不是一个坏主意。但是,如果您必须运行自己的数据库、获得新硬件、没有足够的支持资源,那么引入数据库可能不是一个明智的选择,您可以考虑一种更简单但可能更脆弱的方法来让您的进程写入文件以安排作业和报告任务。

同时,不要将 DB 或 JMS 的引入视为天生容易出错。正确实施它们是稳定且经过验证的技术,将使您的系统具有可扩展性和可管理性。

正如@kan 所说,使用暴露 Web 服务接口也是一个有用的选项。

于 2013-01-24T09:51:05.563 回答
1

您在企业架构中有消息 (JMS) 。使用这些,它们在 Glassfish 等 Java EE 容器中可用。可以对消息进行序列化,以确保即使服务器在队列中重新启动,它们也会被传递。你甚至不需要关心这一切是如何实现的。

于 2013-01-24T09:37:48.373 回答
1

另一种选择是将 B 作为服务,例如将控制和状态接口公开为 REST 或 SOAP 接口。在这种情况下,A 将只是作为 B 的客户端应用程序。B 将其状态存储在数据库中。A 是一个无状态的应用程序,它只与 B 通信。

顺便说一句,使用 Spring Remote,您可以公开一个接口并使用 JMS、REST、SOAP 或 RMI 中的任何一个作为传输层,以后可以在必要时进行更改。

于 2013-01-24T09:40:53.600 回答
0

这里可以有几种方法。首先,正如@kan 建议的那样,让应用 B 公开一些用于交互的 Web 服务。这将使异构客户端与应用程序 B 进行通信。似乎是一个好方法。应用 B 可以在内部使用它认为合适的任何持久性存储。

或者,您可以让应用程序 B 通过 JMX 公开一些管理接口,并让应用程序 A 等应用程序通过此管理接口与应用程序 B 通信。实现任务提交和检索统计信息等会更简单。此外,您还可以利用 JMX 通知来实时更新任务提交和成就等。这样做的缺点是这将是 Java 特定的解决方案,因此支持异构客户端将是遥不可及的梦想。

于 2013-01-24T10:23:03.553 回答