0

我们在 Spring Boot 应用程序中使用 Bitronix XA 作为 jta 事务管理器。问题是它建立的多个连接会占用 MQ 服务器上的资源。我们使用 IBM websphere 作为 MQ 服务器。出于某种原因,Bitronix 不尊重我们提供的池大小。另一个观察结果是,当我们同时接收或发送大量消息时,就会发生连接泄漏。下面是代码中的配置。请告知如何解决连接泄漏问题。

池连接工厂:

PoolingConnectionFactory connectionFactory = new PoolingConnectionFactory();
        connectionFactory.setClassName("com.ibm.mq.jms.MQXAQueueConnectionFactory");
        connectionFactory.setUniqueName(XA_FACTORY_NAME);
        connectionFactory.setAllowLocalTransactions(false);
        connectionFactory.setTestConnections(true);
        connectionFactory.setUser(user);
        connectionFactory.setPassword(password);
        connectionFactory.setMaxPoolSize(20);
        Properties driverProperties = connectionFactory.getDriverProperties();
        driverProperties.setProperty("port",  ...);
        driverProperties.setProperty("transportType", ...);
        driverProperties.setProperty("channel", ...);
        driverProperties.setProperty("hostName", ...);
        driverProperties.setProperty("queueManager", ...);

btm 配置:

@Bean
    @Profile({"cloud", "local"})
    @DependsOn("instanceInfo")
    public bitronix.tm.Configuration btmConfig() {
        bitronix.tm.Configuration btmConfig = TransactionManagerServices.getConfiguration();
        btmConfig.setDisableJmx(true);
        btmConfig.setServerId(instanceInfo);
        return btmConfig;
    }

    @Bean
    @DependsOn("btmConfig")
    public BitronixTransactionManager bitronixTransactionManager() {
        BitronixTransactionManager transactionManager = TransactionManagerServices.getTransactionManager();
        return transactionManager;
    }

SpringIntegrationFlows中使用的消息容器:

private DefaultMessageListenerContainer createMessageContainer(MessageListenerAdapter messageListenerAdapter,
            ConnectionFactory connectionFactory, String queue, JtaTransactionManager jtaTransactionManager) {
        DefaultMessageListenerContainer container = new DefaultMessageListenerContainer();
        container.setMessageListener(messageListenerAdapter);
        container.setConnectionFactory(connectionFactory);
        container.setDestinationName(queue);
        container.setSessionTransacted(true);
        container.setTransactionManager(jtaTransactionManager);
        container.setErrorHandler(containerErrorHandler);
        return container;
    }

用于数据库连接的PoolingDataSource :

  public PoolingDataSource createPooledDataSource(String driverClassName, String userName, String password, String jdbcURL, String validationQuery) {      
        PoolingDataSource dataSource = new PoolingDataSource();
        dataSource.setUniqueName("dataSource");
        dataSource.setMaxIdleTime(8);
        dataSource.setMinPoolSize(1);
        dataSource.setMaxPoolSize(20);
        dataSource.setTestQuery(validationQuery);
        dataSource.getDriverProperties().setProperty("user", userName);
        dataSource.getDriverProperties().setProperty("password", password);
        dataSource.getDriverProperties().setProperty("URL", jdbcURL);
        dataSource.setClassName(driverClassName);
        dataSource.setTestQuery(validationQuery);
        dataSource.setAllowLocalTransactions(true);
        dataSource.init();
        return dataSource;
}
4

1 回答 1

1

听起来像 IBMMQ 从他们的客户端 jar 中提取连接和会话池,如技术说明中所述。这可以解释高于maxPoolSize连接数的原因,特别是如果您没有xaSession明确地 pool 。BTMmaxPoolSize适用于JmsPooledConnection,但那些额外的连接可能来自xaSessions 而不受maxPoolSize.

我不熟悉 Spring 或您的设置,但阅读了使用建议CachingConnectionFactory(例如ref-1ref-2),并且似乎 IBMMQ 对此添加了某些支持(github链接,尤其是how部分。我没有任何经验虽然使用它们....)。

顺便说一句,ShareConversation 也可用于控制连接数,在服务器端默认为 10。IBM 文档 (链接) 提到使用它可能会导致 15% 的性能损失。

于 2018-11-16T19:22:43.350 回答