使用 Java 配置执行器 JMS 健康检查返回误报 [英] Actuator JMS Health Check Return False Positive With Java Configuration

查看:36
本文介绍了使用 Java 配置执行器 JMS 健康检查返回误报的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have run into an issue where the Actuator probe fails for JMS health even though my routes can connect and produce message to JMS. So in short Actuator is saying it is down but it is working.

技术栈和技术说明:

  • 春季启动:2.3.1.RELEASE
  • 骆驼:3.4.1
  • 阿尔忒弥斯:2.11.0
  • Artemis 已设置为使用用户名和密码 (artemis/artemis).
  • 使用 org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory 作为连接工厂.
  • Spring-boot: 2.3.1.RELEASE
  • Camel: 3.4.1
  • Artemis: 2.11.0
  • Artemis has been setup to use a user name and password(artemis/artemis).
  • Using org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory for connection factory.

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

My route is as simple as chips:

  <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.

With Spring-boot favoring java based configuration I am busy migrating our XML beans accordingly.Thus I took a working beans.xml file pasted into the project and fired up the route and I could send messages flowing and the health check returned 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 Configuration

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

I then used the application.yaml file to configure the artemis connection by using this method as outlined in the Spring-boot documentation. This also worked when my application.yaml file contained the following configuration:

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

这就像一个魅力.

勇敢尝试Java配置.

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

So I then went for gold and tried the Java based configuration as outlined below:

@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;
    }
}

所以当骆驼启动时,我在启动时看到以下警告:

So when camel starts up I see the following warning logged on start up:

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 控制台,我可以浏览消息并看到它们正在创建.但是,当我运行执行器运行状况时,我会看到以下内容:

After the 5sec delay the timer kicks in and message are being produced. I logged into the Artemis console and I can browse the messages and can see them being created. However when I run a get on actuator health I see the following:

 "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"
            }
        },

这对我来说是个大错误.

This feels like a big of a bug to me.

关于连接池实现的观察.

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

I noticed that AMQ connection pooling has been moved into the following maven dependency:

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

我想我也试试看.它显示了与上面概述的相同的行为,但还有一件更有趣的事情.当使用 org.messaginghub.pooled-jms 作为连接池(spring-boot 文档也推荐)时,启动时会记录以下内容.

I thought let me give that a try as well. It show the same behaviour as outlined above with one more interesting thing. When using org.messaginghub.pooled-jms as the connection pool(recommended by spring-boot docs as well) the following is logged on startup.

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.

Which is weird as according to the official repo the connector is JMS 2.0 compliant.

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

Quick Summary: It appears that actuator does not pick up the credentials of the connection factory when configuring the JMS component via Java. While a work around exists at the moment by using the spring-boot application.yaml configuration it limits the way you can configure JMS clients on Camel.

推荐答案

所以经过一番挖掘和联系 GitHub 上的 Spring-boot 人员,我发现了问题所在.使用 Java 配置时,我正在使用连接工厂配置 Camel 的 JMS 组件.然而 Spring-boot 完全没有意识到这一点,因为它是一个 Camel 组件.因此,JMS 使用的连接工厂需要暴露给 Spring-boot 才能工作.

So after some digging and reaching out to the Spring-boot people on GitHub, I found what the issue is. When using Java configuration I am configuring the JMS component of Camel with a connection factory. However Spring-boot is completely unaware of this as it is a Camel component. Thus the connection factory used by the JMS needs to be exposed to Spring-boot for it to work.

修复相对简单.见以下代码:

The fix is relatively simple. See code below:

@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;
    }
}

这篇关于使用 Java 配置执行器 JMS 健康检查返回误报的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆