0

我在 tomcat 上部署了一个应用程序,它尝试使用外部系统 A 和 B 的远程 JMS 队列。外部系统部署在 Weblogic 上,因此为了与它们通信,我还提供了 wlthint3client。

那是我的代码:

public void myMethod () {
   // Sending message to first ext system
   // jndi queue name - topic1.extsys1.tosend.messages
   magicMethod(Params of External system A);

   // Sending message to second ext system
   // jndi queue name - topic1.extsys2.tosend.messages
   magicMethod(Params of External system B);

   // AGAIN Sending message to FIRST ext system
   // jndi queue name - topic1.extsys1.tosend.messages
   magicMethod(Params of External system A);  
}

private void magicMethod(String factoryName, String url, String connectionFactoryJNDI, String queueName) throws Exception {

    javax.jms.QueueConnectionFactory queueConnectionFactory = null;
    javax.jms.QueueSession queueSession = null;
    javax.jms.Queue queue = null;
    javax.jms.QueueSender queueSender = null;
    javax.jms.QueueConnection queueConnection = null;
    InitialContext ic = null;

    try {
        final Properties initialContextProperties = new Properties();
        initialContextProperties.put(Context.INITIAL_CONTEXT_FACTORY, factoryName);
        initialContextProperties.put(Context.PROVIDER_URL, url);
        initialContextProperties.put(Context.SECURITY_PRINCIPAL, "");
        initialContextProperties.put(Context.SECURITY_CREDENTIALS, "");
        ic = new InitialContext(initialContextProperties);
        queueConnectionFactory = (QueueConnectionFactory) ic.lookup(connectionFactoryJNDI);
        queue = (javax.jms.Queue) ic.lookup(queueName);
    } catch (NamingException e) {
        System.out.println("Could not create JNDI context: " + e.getMessage());
    }

    try {
        queueConnection = queueConnectionFactory.createQueueConnection();
        queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
        queueSender = queueSession.createSender(queue);
        ObjectMessage objectMessage = queueSession.createObjectMessage("message");
        queueSender.send(objectMessage);
    } catch (JMSException e) {
        System.out.println(e.getMessage());
    } finally {
        ic.close();
        queueConnection.close();
        queueSession.close();
        queueSender.close();
    }
}

当我向分机系统 A 发送消息时 - 一切正常。向分机系统 B 发送消息 - 仍然发送消息,一切正常。

当再次尝试向分机系统 A 发送消息时 - 我失败了。

无法创建 JNDI 上下文:尝试查找“topic1.extsys1.tosend.messages”时未找到子上下文“extsys1”。解决了“主题1”

所以我试图理解:

  1. 我做错了什么?
  2. 为什么在我成功发送到 ext 系统 B 后它没有向系统 A 发送消息?
  3. 这些内部 java 对象(InitialContext、JNDI 对象等)是否在某处具有某种状态?也许我需要清洁的东西?
  4. 我觉得 JNDI 名称有些混乱......
  5. 也许我需要改名?(实际上我已经尝试过使用完全不同的 jndi 队列名称,但没有效果,但是我没有重新启动外部系统,不确定是否需要)。

任何想法,移动方向???请

ps - jms 服务器和 jms 模块在 A 和 B 外部系统中具有相同的名称。提供者 URL 是 - ext1.xxx.corp.com,ext2.xxx.corp.com

4

2 回答 2

0

这是虚拟代码,只是为了描述情况。

答案就在这里 -具有多个代理的 JMSTemplate。目的地解析异常

于 2019-01-16T07:14:50.247 回答
0

我不完全确定 JNDI 查找失败的原因。JNDI 对象没有任何状态,至少不符合规范,但您的特定实现可能有一些非规范行为。这也可能只是您的 JNDI 实现中的一个错误。

但是,我可以说您的代码在这里使用了重要的反模式,因为它对您发送的每条消息都执行以下操作:

  • JNDI 查找(可能需要网络往返)
  • 创建 JMS 连接(当然需要网络往返)
  • 创建 JMS 会话(几乎可以肯定需要网络往返)
  • 创建 JMS 生产者

这是对资源的极大浪费。至少您应该缓存 JNDI 查找的结果(这可能会解决您的问题)以及您的 JMS 连接工厂。理想情况下,您会为 JMS 连接使用池。

于 2019-01-16T01:17:37.147 回答