【问题标题】:JMS connection pooling with IBM MQ Client使用 IBM MQ 客户端的 JMS 连接池
【发布时间】:2020-10-29 16:10:42
【问题描述】:

我们在 IBM MQ 9.x 服务器和 IBM MQ 客户端之间使用 MQIPT 9.2。我们还使用 Java 中的 IBM MQ 客户端 jar 连接到队列管理器以推送和接收运行良好的消息。然而,连接创建需要时间,如果我们及时创建连接,每次都需要时间。

我们如何为 IBM MQ 实现 JMS 连接池?

以下描述了我们的连接性:

[][1

有什么标准方法可以实现连接池吗?

下面使用的代码

System.out.println("<<<<<<<<<Starting test for push messages>>>>>>>>>>");

try {

    // Create a keystore object for the truststore
    KeyStore trustStore = KeyStore.getInstance("JKS");
    char[] keyPassphrase = "*******".toCharArray();
    trustStore.load(new FileInputStream(
            "JKS File path"),
            keyPassphrase);
    TrustManagerFactory trustManagerFactory = TrustManagerFactory
            .getInstance(TrustManagerFactory.getDefaultAlgorithm());
    trustManagerFactory.init(trustStore);
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
    SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
    System.out.println("SSL certificates loaded in message sending");
    // Create default MQ connection factory
    MQQueueConnectionFactory factory = new MQQueueConnectionFactory();
    factory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
    factory.setQueueManager(QMGRNAME);
    factory.setHostName(HOSTNAME);
    factory.setChannel(CHANNEL);
    factory.setPort(1414);
    factory.setSSLFipsRequired(false);
    factory.setSSLSocketFactory(sslSocketFactory);
    factory.setClientReconnectTimeout(100);
    factory.setStringProperty(WMQConstants.USERID, user);
    factory.setStringProperty(WMQConstants.PASSWORD, password);
    factory.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP, true);

    factory.setStringProperty(WMQConstants.WMQ_SSL_CIPHER_SUITE, "cipher suite");


    mqConnection = (MQQueueConnection) factory.createQueueConnection();
    
    
    MQQueueSession session = (MQQueueSession) mqConnection.createQueueSession(false,
            Session.AUTO_ACKNOWLEDGE);
    // Start the connection
    System.out.println("Connection starting while sending message");
    mqConnection.start();
    System.out.println("Connection started while sending message");
    for (int i = 0; i <50; i++) {
        System.out.println("Preparing message before sending");
        long uniqueNumber = System.currentTimeMillis() % 1000;
        JMSTextMessage message = (JMSTextMessage) session
                .createTextMessage("SimplePTP - msg" + uniqueNumber);
        System.out.println("message prepared while sending , text: " + message.getText());
        Destination destination = session.createQueue(destinationName);
        MQMessageProducer producer = (MQMessageProducer) session.createProducer(destination);

        // And, send the message
        producer.send(message);
        System.out.println("Sent message****************:\n" + message);
    }

    /*
     * if (connection != null) { System.out.
     * println("*************connection closing after message sent********************"
     * ); connection.close(); System.out.
     * println("*************connection closed after message sent********************"
     * ); }
     */
    System.out.println("<<<<<<<<<<Test ended>>>>>>>>>>>>");
} catch (JMSException j) {
    j.printStackTrace();
} catch (Exception e) {
    e.printStackTrace();
} finally {
    System.out.println("finally block after message sent************ ");
    if (mqConnection != null) {
        try {
            mqConnection.close();
            System.out.println("connection closed after message sent in finally block\n");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    System.out.println("<<<<<<<<<<Test ended from finally >>>>>>>>>>>>");
}

当使用上述代码时,连接创建需要时间,它会为每个消息创建和关闭一个连接。这是一个不好的做法,所以我创建了一个列表并将连接添加到其中,效果很好。但是,我想改用适当的连接池。

【问题讨论】:

  • 您是独立运行 jns 应用程序还是在 J2EE 应用服务器中运行?
  • 能否在MQ客户端展示你的JMS相关代码?
  • 添加了有问题的代码。我们也将此与 Camel JMS 路由一起使用,但骆驼正在为每条消息创建新连接
  • Spring有一个缓存连接工厂,这个可以用吗?

标签: jms ibm-mq spring-jms


【解决方案1】:

你可以使用:

<bean class="org.apache.activemq.jms.pool.PooledConnectionFactory"
       id="source.pooledConnectionFactory" primary="true">
    <property name="maxConnections" value="1"/>
    <property name="idleTimeout" value="0"/>
    <property name="connectionFactory" ref="factory"/>
</bean>

(对于您发布 Java DSL 时的 XML 感到抱歉,但您明白了)。基本上,使用 ActiveMQ JMS 池连接工厂包装您的连接工厂。

或者,您可以使用:

    <dependency>
        <groupId>org.messaginghub</groupId>
        <artifactId>pooled-jms</artifactId>
        <version>1.1.0</version>
    </dependency>


    JmsPoolConnectionFactory pooledCF = new JmsPoolConnectionFactory();
    
    pooledCF.setConnectionFactory(connectionFactory());
    pooledCF.setMaxConnections(1);

org.messaginghub 项目是 ActiveMQ 代码的一个分支,没有 ActiveMQ 依赖项。

【讨论】:

  • Doug,他使用的是 IBM MQ 而不是 ActiveMQ。 ActiveMQ JMS 池连接工厂是否与 IBM MQ 连接工厂一起使用?
  • 是的。请注意,这是 'org.apache.activemq.jms' (jms) 变体。它旨在包装任何 JMS 连接工厂。还有另一种专门为 ActiveMQ 连接工厂设计的变体。 messaginghub fork 几乎相同,但删除了连接超时。
  • github 对于那些感兴趣的人。
  • 如何使用池 jms 设置最大连接限制
  • 同上,带有setMaxConnections()函数。但是请注意,Spring JMS 代码将创建一个连接,然后在该连接上启动多个 JMS 会话。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-08
  • 2019-03-17
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 2013-03-28
  • 2011-03-04
相关资源
最近更新 更多