【问题标题】:No error thrown if message is sent to a non-existent topic如果将消息发送到不存在的主题,则不会引发错误
【发布时间】:2015-09-02 19:35:02
【问题描述】:

当使用 IBM.XMS 向不存在的主题发送消息时,不会引发异常。当尝试对队列进行相同操作时,我会收到队列管理器或队列不存在的通知。

这是我创建连接并向主题发送消息的方式:

XMSFactoryFactory xmsFactoryFactory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);
IConnectionFactory ibmConnectionFactory = xmsFactoryFactory.CreateConnectionFactory();
ibmConnectionFactory.SetStringProperty(XMSC.WMQ_HOST_NAME, "frimasrv");
ibmConnectionFactory.SetIntProperty(XMSC.WMQ_PORT, 1415);
ibmConnectionFactory.SetStringProperty(XMSC.WMQ_CHANNEL, "CH1");
ibmConnectionFactory.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, XMSC.WMQ_CM_CLIENT);
ibmConnectionFactory.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, "API");

IConnection connection = ibmConnectionFactory.CreateConnection();
connection.ClientID = "client id";
ISession session = connection.CreateSession(false, AcknowledgeMode.AutoAcknowledge);

IDestination destination = session.CreateTopic("this.does.not.exist");
IMessageProducer producer = session.CreateProducer(destination);
IMessageConsumer durableConsumer = session.CreateDurableSubscriber(destination, "subscriptionName");

IMessage myMessage = session.CreateTextMessage("text");
producer.Send(myMessage);

用 session.CreateQueue(...) 补充 session.CreateTopic(...) 的调用, session.CreateProducer(...) 会失败。这也是我在使用主题时所期望的行为。

我的问题是:

发送到不存在的主题时怎么没有问题? 我的部分配置错误吗? 是否有其他方法可以验证主题是否确实存在?

【问题讨论】:

    标签: c# ibm-mq


    【解决方案1】:

    为什么发送到一个没有问题的主题时没有出现问题 存在?

    因为在您向主题发送消息或订阅主题的那一刻,它就存在。队列管理器将为您自动激活它。

    根据 JMS 2.1 规范:

    某些产品要求使用静态定义的主题 关联的授权控制列表等;其他人甚至没有 有主题管理的概念。

    IBM MQ 是不需要静态定义主题的产品之一。

    您可能误解了 IBM MQ 对主题对象的使用。它们本身并不定义主题,而是提供了一个指针,指向主题层次结构中应用访问控制列表的位置。例如,考虑以下主题层次结构:

    Produce
       Fruits
          Apple
          Banana
          Cranberry
       Vegetables
          Asparagus
          Beet
          Celery
    

    如果您 define a topic Fruits 并将其指向主题字符串 Produce/Fruits,则您可以授权人们从 Produce/Fruits 向下发布或订阅主题树的部分。拥有授权的人将无法访问Produce/Vegetables,除非您通过指向那里的主题对象向他们提供访问权限。

    通常,最好在主题树的某个级别定义主题对象。正如您在上面看到的,在Produce 定义一个主题对象会授予对整个主题树的访问权限,但您只需要一个主题对象。在第二级定义对象,您需要两个来覆盖树(一个在Fruits,一个在Vegetables),但在安全模型中具有更高的粒度。在第三级定义主题,您可以拥有极高的粒度,但也有更多的主题对象需要管理。

    IBM MQ 定义了一个默认主题对象SYSTEM.BASE.TOPIC,它指向全局主题空间的根。任何有权访问SYSTEM.BASE.TOPIC 的人都可以访问任何主题。默认情况下,这仅包括 MQ 管理员。

    如果您定义一个名为Fruits 的主题并将其指向主题字符串Produce/Fruits,那么当您要打开该主题时有两种选择。如果您打开主题 object,这会导致 IBM MQ 替换对象指向的主题 string。您也可以直接打开主题字符串。由于 IBM MQ 始终根据最终主题字符串进行授权,因此这些中的任何一个都会产生相同的有效授权。

    如果您同时指定主题对象主题字符串,则已定义对象中的主题字符串用作您提供的字符串的前缀。将两者连接起来以生成完整的主题字符串。例如,如果您同时指定主题对象Fruits(在上例中指向字符串Produce/Fruits字符串Produce/Fruits,MQ 将连接这些并激活了一个名为Produce/Fruits/Produce/Fruits的主题。尽量不要那样做。如果您确实需要这样做,请确保您了解Combining topic strings 页面中描述的机制。

    如果您检查 IBM MQ Pub/Sub API 或主题连接工厂的 IBM 实现,您将看到它们包含两个字段,一个用于主题对象,一个用于主题字符串。

    当您在连接工厂中指定主题对象 时,该对象必须 存在。指定一个主题字符串,如果您被授权使用该字符串,MQ 将自动为您激活它。

    我猜您使用的 ID 具有管理员权限或已被授予访问 SYSTEM.BASE.TOPIC 的权限,因为您完全可以发布。因此,对于您发布到的任何主题字符串,您都不会收到任何错误。

    另请参阅手册中的 Topic Strings 页面,了解 IBM MQ 如何管理主题的一般背景。

    【讨论】:

    • 哇,感谢您提供的非常棒的答案。我从 qm.ini 中删除了身份验证,所以我猜这在这里有一些含义。
    • 是的,会的。请注意,一旦您禁用 OAM,您将永远无法再次打开它。您必须从头开始删除并重新创建 QMgr,然后重新构建所有对象,然后才能再次可靠地使用 MQ 授权。
    • 太棒了! @T.Rob。谢谢。
    【解决方案2】:

    您是否运行过“IBM Message Service Client for .NET”安装程序?

    XMS : XmsFactoryFactory moans about missing IBM.XMS.Impl

    这是另一个关于 SO 的有用帖子:

    How do I get Websphere MQ connection status and how do I reset the connection:

    【讨论】:

    • 感谢您的回答。客户端安装完成,所有程序集都可用。第二个链接看起来涉及不同的库,但我会调查一下!
    猜你喜欢
    • 2017-03-29
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-17
    • 1970-01-01
    相关资源
    最近更新 更多