Java 如何设计MQ服务器?

Java 如何设计MQ服务器?,java,architecture,jms,ibm-mq,Java,Architecture,Jms,Ibm Mq,我不清楚以下两者之间是否应该存在1-1或1-*关系: 服务器连接通道和JMS主题 服务器连接通道和侦听器 听众与话题 关于我们应用层的设计,有一个MDB,它响应消息,做一些工作,然后将消息发布到各种输出主题上。服务层正在侦听这些输出主题 目前,我有一个1-1-1通道侦听器主题,因此每个发布服务器(在应用程序端)和侦听器(在服务端)都有一个JmsConnectionFactory实例 容器中的MDB创建一个并发处理消息的MDB池。如果你只是简单地处理并写下主题,你会很好。记住这一点,你没有1-1-

我不清楚以下两者之间是否应该存在1-1或1-*关系:

  • 服务器连接通道和JMS主题
  • 服务器连接通道和侦听器
  • 听众与话题
  • 关于我们应用层的设计,有一个MDB,它响应消息,做一些工作,然后将消息发布到各种输出主题上。服务层正在侦听这些输出主题


    目前,我有一个1-1-1通道侦听器主题,因此每个发布服务器(在应用程序端)和侦听器(在服务端)都有一个JmsConnectionFactory实例

    容器中的MDB创建一个并发处理消息的MDB池。如果你只是简单地处理并写下主题,你会很好。记住这一点,你没有1-1-1关系


    在MDB中,只需对TopicConnectionFactory和主题进行JNDI查找,然后编写。看看这里:

    有几种不同的方法来看待这个问题。从应用程序的角度来看,一个连接工厂可以有多个会话。每个会话可能有许多使用者,但工作单元的范围是每个会话,而不是每个使用者。因此,您很可能希望一个连接工厂具有多个会话,其中每个会话都有一个特定主题的侦听器。如果在单个会话中将侦听器分配给多个使用者,则任何确认(或事务会话中的提交)都会提交在该会话中获取或放置的所有消息

    从WMQ服务器的角度来看,一个通道定义可以有多个运行实例。因此,无论需要启动多少通道实例,每个应用程序只需要定义一个SVRCONN通道。但是,不要将不同的应用放在同一个SVRCONN上,因为您通常希望分别管理或授权这些应用。例如,使用单独频道上的应用程序,如果您突然发现自己有3000个正在运行的频道,您可以很容易地找出哪个应用程序出现了问题

    出于管理和调试的目的,我可能会有一个CF用于应用程序端,一个CF用于服务端。如上所述,每个都指向不同的SVRCONN通道。在应用服务器内部,我会坚持每个会话一个主题,除非你的应用在一个工作单元中消耗多个主题是有效的。在订阅中,您可以指定通配符主题,以使用单个订阅服务器获取主题树中某个点以下的所有主题

    为了获得最佳实践,我还将CF设置为使用FAILIFQUIESCE,以确保QMgr可以有序地停止,并使用SYNCPOINTALLGETS(或带有显式提交调用的事务会话),以根据JMS 1.1规范第4.4.13节提高可靠性,该节规定:

    如果在客户机提交其会话工作和提交方法返回之间发生故障,则客户机无法确定事务是否已提交或回滚。当持久消息的非事务性发送和发送方法的返回之间发生故障时,同样存在模糊性。由JMS应用程序来处理这种模糊性。在某些情况下,这可能会导致客户端生成功能上重复的消息

    由于会话恢复而重新传递的消息不被视为重复消息

    SYNCPOINTALLGETS(又称SPAG)确保从队列中检索到的消息在提交并从队列中永久删除之前传递到您的应用程序。否则,如果在QMgr尝试返回消息时丢失连接,则消息将永远消失。使用SPAG集合,您可能会像JMS规范中所描述的那样看到同一消息两次,但您永远不会删除一条消息

    有关CF、队列和主题对象可用选项的更多详细信息,请参阅WebSphere MQ使用Java手册中的


    WMQ v6.0从2012年9月起已停止使用,因此请确保使用v7客户端进行开发,即使服务器是v6。这将减少您明年的迁移工作。下载v7客户端和WMQ v7.1客户端。

    Hi-Romain。我不清楚您是否建议当前的设计不是1-1-1,或者您所建议的使用JNDI使其成为1-1-1。希望是后者,在这种情况下,我应该删除除一个外的所有通道,并使
    JmsTopicConnectionFactory
    使用这一个通道。如果是前者,我很困惑。我想说的是,你不是1-1-1,因为你是池。我不确定问题是什么,您所需要做的就是创建MDB,然后它将侦听入站队列。然后MDB执行JNDI查找(实际上只是检索一个序列化对象,实际上是两个),然后执行代码发布到主题。看看这个