处理消费者端的失败调用(在生产者/消费者模型中)

时间:2013-02-12 18:56:17

标签: java asynchronous jms publish-subscribe tibco

让我试着解释一下情况:

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

1)制作人/发布者:有服务A. A生成消息并写入队列/主题

2)消费者/订阅者:有一个服务B. B异步读取来自队列/主题的消息。 B然后调用Web服务并将消息传递给它。 Web服务需要大量时间来处理消息。 (此操作无需实时处理。)

Message Broker是Tibco

我的意图是:不要错过处理来自A的任何消息。如果处理第一次失败(可能是批处理),请在以后重新处理它。

问题

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

写入数据库是一种典型的做法吗?

4 个答案:

答案 0 :(得分:0)

由于你有一个失败的回调,你可以重新排队Message并让你的Consumer/Subscriber拿起它再试一次。如果由于Web服务中的某些问题导致失败并且您希望在再次尝试之前等待X时间,那么您可以安排在以后针对该特定Message调用Web服务(查看{ {3}})或按照您的描述执行并使用带有一些数据库条目的cron作业。

如果您只希望每封邮件再尝试一次,请将内部计数器与MessageMap<Message, Integer>内的计数器作为每个Message的计数器。

答案 1 :(得分:0)

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

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

答案 3 :(得分:0)

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

你需要知道第一个决定是:

  • 你需要按顺序交货吗? (然后只应使用1个JMS会话和客户端确认模式)
  • 您想重试的频率和重复次数是多少? (不要对该Web服务无法处理的消息进行无限循环)。

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

对于“按顺序”传递:仅使用shure 1 JMS会话处理消息并使用客户端acknolwedge模式。在成功处理消息之后,您需要通过调用JMS API“acknowledge()”方法或通过执行“commit”活动在TIBCO BW中确认消息。

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

EMS的显式客户端Acknolwedge模式还允许您在订单不重要且需要一些客户端线程来处理消息时执行相同操作。

为了控制消息处理的频率,请使用:

    EMS队列的
  • 最多重新传送属性(例如,您可以将邮件置于死机中 字母队列afer x redelivery不能阻止其他消息)
  • 重新发送延迟在重新发送之间设置“暂停”。这在以下情况下非常有用 发生崩溃后,Web服务需要恢复,并且不会再次通过重新传输在高级间隔内被同一消息攻击。

希望有所帮助

干杯      SEB