执行器 JMS 运行状况检查使用 Java 配置返回误报

问题描述 投票:0回答:1

我遇到了一个问题,即执行器探测 JMS 运行状况失败,即使我的路由可以连接并向 JMS 生成消息。简而言之,执行器说它已关闭,但它正在工作。

技术堆栈和技术说明:

  • Spring 启动:2.3.1.RELEASE
  • 骆驼:3.4.1
  • 阿尔忒弥斯:2.11.0
  • Artemis 已设置为使用用户名和密码(artemis/artemis)。
  • 使用
    org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory
    作为连接工厂。

我的路线就像筹码一样简单:

  <route id="timer-cluster-producer-route">
            <from uri="timer:producer-ticker?delay=5000"/>
          
            <setBody>
                <groovy>
                    result = ["Name":"Johnny"]
                </groovy>
            </setBody>
            <marshal>
                <json library="Jackson"/>
            </marshal>
            <to uri="ref:jms-producer-cluster-event" />
   </route>

基于 XML 的 Artemis 配置

随着 Spring-boot 支持基于 java 的配置,我正忙于相应地迁移我们的 XML beans。因此,我将一个工作 beans.xml 文件粘贴到项目中并启动了路由,我可以发送消息流,并且运行状况检查返回正常。


<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
         http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
    <bean id="jmsConnectionFactory"
        class="org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory">
        <property name="brokerURL" value="tcp://localhost:61616" />
        <property name="user" value="artemis"/>
        <property name="password" value="artemis"/>
        <property name="connectionLoadBalancingPolicyClassName" value="org.apache.activemq.artemis.api.core.client.loadbalance.RoundRobinConnectionLoadBalancingPolicy"/>
    </bean>
    <!--org.messaginghub.pooled.jms.JmsPoolConnectionFactory-->
    <!--org.apache.activemq.jms.pool.PooledConnectionFactory-->
    <bean id="jmsPooledConnectionFactory"
        class="org.apache.activemq.jms.pool.PooledConnectionFactory"
        init-method="start" destroy-method="stop">
        <property name="maxConnections" value="64" />
        <property name="MaximumActiveSessionPerConnection"
            value="500" />
        <property name="connectionFactory" ref="jmsConnectionFactory" />
    </bean>
    <bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
        <property name="connectionFactory"
            ref="jmsPooledConnectionFactory" />
        <property name="concurrentConsumers" value="1" />
        <property name="artemisStreamingEnabled" value="true"/>
    </bean>
    <bean id="jms"
          class="org.apache.camel.component.jms.JmsComponent">
        <property name="configuration" ref="jmsConfig"/>

    </bean>

<!--    <bean id="activemq"
        class="org.apache.activemq.camel.component.ActiveMQComponent">
        <property name="configuration" ref="jmsConfig" />
    </bean>-->
    

</beans>


Spring-boot Auto(黑色)神奇配置

然后,我使用 application.yaml 文件通过使用 Spring-boot 文档中概述的此方法来配置 artemis 连接。当我的 application.yaml 文件包含以下配置时,这也有效:

artemis:
  user: artemis
  host: localhost
  password: artemis
  pool:
    max-sessions-per-connection: 500
    enabled: true
    max-connections: 16

这就像一个魅力。

Java 配置的勇敢尝试。

因此,我选择了黄金并尝试了基于 Java 的配置,如下所述:

@SpringBootApplication
@ImportResource("classpath:/camel/camel.xml")
public class ClusterProducerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ClusterProducerApplication.class, args);
    }
    @Bean
    public JmsComponent jms() throws JMSException {
        // Create the connectionfactory which will be used to connect to Artemis
        ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory();
        cf.setBrokerURL("tcp://localhost:61616");
        cf.setUser("artemis");
        cf.setPassword("artemis");

        //Create connection pool using connection factory
        PooledConnectionFactory pooledConnectionFactory = new PooledConnectionFactory();
        pooledConnectionFactory.setMaxConnections(2);
        pooledConnectionFactory.setConnectionFactory(cf);

        //Create configuration which uses connection factory
        JmsConfiguration jmsConfiguration = new JmsConfiguration();
        jmsConfiguration.setConcurrentConsumers(2);
        jmsConfiguration.setArtemisStreamingEnabled(true);
        jmsConfiguration.setConnectionFactory(pooledConnectionFactory);

        // Create the Camel JMS component and wire it to our Artemis configuration
        JmsComponent jms = new JmsComponent();
        jms.setConfiguration(jmsConfiguration);
        return jms;
    }
}

因此,当骆驼启动时,我会看到启动时记录以下警告:

020-07-28 12:33:38.631  WARN 25329 --- [)-192.168.1.158] o.s.boot.actuate.jms.JmsHealthIndicator  : JMS health check failed

javax.jms.JMSSecurityException: AMQ229031: Unable to validate user from /127.0.0.1:42028. Username: null; SSL certificate subject DN: unavailable

5 秒延迟后,计时器启动并生成消息。我登录了 Artemis 控制台,可以浏览消息并看到它们正在创建。但是,当我运行获取执行器运行状况时,我看到以下内容:

 "jms": {
            "status": "DOWN",
            "details": {
                "error": "javax.jms.JMSSecurityException: AMQ229031: Unable to validate user from /127.0.0.1:42816. Username: null; SSL certificate subject DN: unavailable"
            }
        },

这对我来说感觉像是一个大错误。

有关连接池实现的观察。

我注意到 AMQ 连接池已移至以下 Maven 依赖项中:

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

我想我也尝试一下。它显示了与上面概述相同的行为,但还有一件更有趣的事情。当使用

org.messaginghub.pooled-jms
作为连接池时(spring-boot 文档也推荐),启动时会记录以下内容。

2020-07-28 12:41:37.255  INFO 26668 --- [           main] o.m.pooled.jms.JmsPoolConnectionFactory  : JMS ConnectionFactory on classpath is not a JMS 2.0+ version.

这很奇怪,因为根据 官方存储库,连接器符合 JMS 2.0。

快速总结: 通过 Java 配置 JMS 组件时,执行器似乎不会获取连接工厂的凭据。虽然目前存在使用 spring-boot application.yaml 配置的解决方法,但它限制了您在 Camel 上配置 JMS 客户端的方式。

spring-boot apache-camel activemq-artemis
1个回答
6
投票

经过一番挖掘并联系 GitHub 上的 Spring Boot 人员,我发现了问题所在。使用 Java 配置时,我使用连接工厂配置 Camel 的 JMS 组件。然而 Spring-boot 完全不知道这一点,因为它是一个 Camel 组件。因此,JMS 使用的连接工厂需要暴露给 Spring-boot 才能工作。

修复相对简单。请参阅下面的代码:

@Configuration
public class ApplicationConfiguration {
    private ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory();
    @Bean
    public JmsComponent jms() throws JMSException {
        // Create the connectionfactory which will be used to connect to Artemis
        cf.setBrokerURL("tcp://localhost:61616");
        cf.setUser("artemis");
        cf.setPassword("artemis");
        
        // Setup Connection pooling
        PooledConnectionFactory pooledConnectionFactory = new PooledConnectionFactory();
        pooledConnectionFactory.setMaxConnections(2);
        pooledConnectionFactory.setConnectionFactory(cf);
        JmsConfiguration jmsConfiguration = new JmsConfiguration();
        jmsConfiguration.setConcurrentConsumers(2);
        jmsConfiguration.setArtemisStreamingEnabled(true);
        jmsConfiguration.setConnectionFactory(pooledConnectionFactory);
        // Create the Camel JMS component and wire it to our Artemis connectionfactory
        JmsComponent jms = new JmsComponent();
        jms.setConfiguration(jmsConfiguration);
        return jms;
    }
    /*
       This line will expose the connection factory to Spring-boot.
    */
    @Bean
    public ConnectionFactory jmsConnectionFactory() {
        return cf;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.