【问题标题】:Multithreaded JMS application多线程 JMS 应用程序
【发布时间】:2010-09-22 23:13:41
【问题描述】:

我正在编写多线程 JMS 接收器和发布器代码。 从队列接收 XML 消息,调用存储过程(执行需要 70 秒)并在 90 秒内将响应发送到主题。 当经纪人倒闭时,我需要处理一个条件。 即从 Queue 接收消息并在 java 中处理消息的情况,同时 Queue 和 Topic 都将关闭。那么如何处理那些不在队列中并且不发送到主题但在java内存中的消息? 可用的不同选项:

1.使用 CLIENT_ACKNOWLEDGE 2.将发布者代码与接收者代码分开。 3.拥有错误实用程序,它将从日志中获取消息并处理它们并发送到主题(最不喜欢)

请给我正确的选择

【问题讨论】:

    标签: java jms


    【解决方案1】:

    使用事务处理会话。在单个工作单元下消费消息并发送响应,并在发送响应后显式调用 COMMIT。然后,如果代理在事务未完成时死亡,则输入消息将回滚。如果您在两阶段协调事务中包含数据库更新,那么它也可以在代理出现故障时回滚。这要求消费者和响应者在同一个线程中,因为 JMS 为每个线程确定会话范围,但您可以让多个线程并行运行会话。

    请注意,将许多事务保持打开 90 秒可能需要在代理端进行一些调整。

    【讨论】:

    • 我相信如果会话被处理,确认模式(例如CLIENT_ACKNOWLEDGE)被忽略:)
    • 是的,我正在考虑我的 WMQ 帽子。我们通常在托管对象中设置 CLIENT_ACKNOWLEDGE,因为它被设置为 something 并且任何阅读它的人都知道代码应该显式提交。然而,从 JMS 的角度来看,它并没有做任何事情。我已经从我的回复中编辑了它。 +1 好收获。
    • 非常感谢!如果不是 connection.createSession(false, javax.jms.Session.CLIENT_ACKNOWLEDGE) ,我将使用 connection.createSession(true, javax.jms.Session.CLIENT_ACKNOWLEDGE);然后处理会话并忽略确认模式。发送对主题的响应后,我将提交()会话。我的问题是,如果在某些异常情况下回滚会话(例如代理关闭并且无法将响应发送到主题),那么该消息仍然存在于队列中,即当代理在 10 分钟后返回时,该消息仍在队列中?
    • 是的。在 COMMIT 调用成功之前,不会删除该消息。如果代理或应用程序出现故障,则消息将回滚(可能直到 TCP 超时并告诉代理应用程序已消失)。当消息处于等待 COMMIT 的同步点时,没有其他使用者会看到该消息实例。回滚后,该队列上的任何消费者都有资格再次接收它。
    • 谢谢!但我面临一个新问题。由于事务中的一些异常,消息被回滚并重新传递。他们一次又一次地回滚并继续,直到我终止程序。这件事我想避免。可以限制重新发货的次数吗?
    【解决方案2】:

    一种解决方案是将 db 用于中间存储过程。所以步骤是:

    1. Consume Message from Queue and store into db and use Client_Acknowledge.
    2. Run stored procedures on the consumed message.
    3. Once the procedure is over, send message from db to the topic.
    4. Delete message once acknowledgement is recieved.
    

    如果队列和主题之间出现故障,您只需在未收到主题确认时再次发送消息。

    嗯,我不确定这是否是最好的选择,并想看看社区如何回应这个问题。

    【讨论】:

    • 在数据库中存储消息不可行,只需要从java调用存储过程(一些数据库约束)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-08
    • 2017-05-15
    • 1970-01-01
    相关资源
    最近更新 更多