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

标签 spring-boot apache-camel

我遇到了一个问题,即使我的路由可以连接并生成到 JMS 的消息,但执行器探针仍会因 JMS 运行状况而失败。所以简而言之,执行器说它已关闭,但它正在工作。
技术栈和技术说明:

  • Spring Boot :2.3.1.RELEASE
  • Camel :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 bean。因此,我将一个工作 beans.xml 文件粘贴到项目中并启动了路由,我可以发送消息流动并且健康检查返回 OK。
    
    <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 (Black)Magic 配置
    然后我使用 application.yaml 文件通过使用 this method 来配置 artemis 连接如 Spring-boot 文档中所述。当我的 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;
        }
    }
    
    因此,当 Camel 启动时,我在启动时看到以下警告:
    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 控制台,可以浏览消息并看到它们正在创建。但是,当我运行 get on actuator health 时,我看到以下内容:
     "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.
    
    
    根据 the official repo,这很奇怪连接器符合 JMS 2.0。
    快速摘要:
    通过 Java 配置 JMS 组件时,执行器似乎没有获取连接工厂的凭据。虽然目前通过使用 spring-boot application.yaml 配置存在变通方法,但它限制了您在 Camel 上配置 JMS 客户端的方式。

    最佳答案

    所以经过一些挖掘和reaching out to the Spring-boot people on GitHub ,我找到了问题所在。使用 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;
        }
    }
    

    关于spring-boot - 执行器 JMS 运行状况检查使用 Java 配置返回误报,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63126305/

    相关文章:

    java - Apache Camel - 在处理器中设置值

    java - 使用 Apache Camel 访问 Azure 服务总线?

    java - 如何针对特定场景正确使用Apache Camel?

    spring - Kafka 消费者没有正确提交偏移量

    spring-boot - jar和构建jar的任务之间的Spring Boot问题:Gradle

    spring - 如何在spring boot mvc中执行请求之前修改Http headers

    apache-camel - 在 onException block 中将处理设置为 true 可防止重新传递

    apache - 端点 : Endpoint[direct://LookUpRoute] 上没有可用的消费者

    java - 其他文件中的 JSP 模板 - Spring Boot

    spring-boot - gradle连续构建技巧在docker容器中不起作用