0

让我试着解释一下情况:

我们将要合并一个消息传递系统,它可以是队列或主题(JMS 术语)。

1)Producer/Publisher:有一个服务A。A产生消息并写入一个Queue/Topic

2)Consumer/Subscriber:有一个服务B。B从Queue/Topic异步读取消息。B 然后调用 Web 服务并将消息传递给它。Web 服务需要花费大量时间来处理消息。(此动作不需要实时处理。)

消息代理是 Tibco

我的意图是:不要错过处理来自 A 的任何消息。在稍后的时间点重新处理它,以防处理第一次失败(可能作为批处理)。

问题

我正在考虑在进行网络服务调用之前将消息写入数据库。如果调用成功,我会将消息标记为已处理。否则失败。后来,在一个 cron 作业中,我将处理所有最初失败的请求。

写入数据库是执行此操作的典型方式吗?

4

4 回答 4

0

粗略地说,这就是技术,尽管您可以使用开箱即用的解决方案。典型的 ESB 解决方案支持可靠的消息传递。也可以看看MuleESBApache ActiveMQ

于 2013-02-12T19:12:10.443 回答
0

利用您已有的 EMS 平台(示例 1)而不是构建自定义解决方案(示例 2)可能会很有趣。

但这一切都取决于实现语言:

示例 1 - EMS 是“守护者”:如果我要使用 TIBCO BusinessWorks 解决此类问题,我会使用 BW 的“JMS 事务”功能。通过将 EMS 读取和 WS 调用包含在同一个“组”中,您要求它们都被应用,或者根本不应用。如果由于某种原因呼叫失败,消息将返回给 EMS。此解决方案有两个问题:您可能没有 BW,并且第一个失败的操作会阻塞批处理的所有其余部分(这可能是所需的行为)。仅供参考,我知道可以在“纯 java”中使用此类功能,但我从未尝试过:http ://www.javaworld.com/javaworld/jw-02-2002/jw-0315-jms.html

示例 2 - 数据库是“守护者”:如果您使用“数据库”方法,您的队列/主题客户会不断地将插入数据放入数据库中,并且所有记录都代表要执行的任务。这感觉很像每个集成中间件旨在简化的简单“映射引擎”问题。您可以使用任何东西来解决这个问题,从自定义 java 代码和多个线程(DB 插入器、WS 作业处理程序等)到 EAI 中间件(如 BW)甚至 BPM 引擎(TIBCO 有很多解决方案)当然,有也是其他供应商...如您所知,EMS 是 JMS 标准实现。

于 2013-02-14T02:31:14.647 回答
0

我建议使用内置的 EMS (& JMS) 功能,因为“保证交付”是它的目的;) - 根本不需要数据库...

您需要知道,第一个决定将是:

  • 你需要按顺序交货吗?(那么应该只使用 1 个 JMS Session 和 Client Ack 模式)
  • 您想要重试的频率和重复次数?(不要使该 Web 服务无法处理的消息无限循环)。

无论您使用哪种客户端(TIBCO BW 或例如 MDB 中的 Java onMessage()),这都是独立的。

对于“按顺序”交付:使舒尔只有 1 个 JMS 会话处理消息,并且它使用客户端确认模式。成功处理消息后,您需要通过调用 JMS API“acknowledge()”方法或在 TIBCO BW 中通过执行“commit”活动来确认消息。

如果发生错误,您不执行该方法的确认,因此消息将被放回队列中以进行重新传递(您可以在 JMS 标头中看到它被重新传递了多少次)。

如果顺序不重要并且您需要一些客户端线程来处理消息,EMS 的显式客户端确认模式也使您能够执行相同的操作。

用于控制消息处理的频率:

  • EMS 队列的最大重新传递属性(例如,您可以在 x 重新传递之后将消息放入死信队列中,以免阻止其他消息)
  • 重新交付延迟在重新交付之间放置一个“暂停”。如果 Web 服务需要在崩溃后恢复并且不会通过重新传递以高间隔一次又一次地被同一消息冲击,这很有用。

希望有帮助

干杯赛布

于 2013-03-02T10:13:48.440 回答
0

由于您有一个失败的回调,您可以重新排队Message并让您Consumer/Subscriber拿起它并重试。如果由于 Web 服务中的某些问题而失败,并且您想在重试之前等待 X 时间,那么您可以安排 Web 服务在以后为特定的日期调用Message(查看ScheduledExecutorService)或按照您的操作描述并使用带有一些数据库条目的 cron 作业。

如果您只希望它在每条消息中再试一次,则使用内部计数器Message或在 aMap<Message, Integer>中作为每个 的计数器Message

于 2013-02-12T19:06:35.740 回答