当前位置: 首页 > 知识库问答 >
问题:

Java配置的执行器JMS健康检查返回误报

龙越彬
2023-03-14

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

技术堆栈和技术注释:

  • Spring防尘套:2.3.1。释放

我的路线就像薯条一样简单:

  <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。于是我拿了一个工作豆。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启动自动(黑色)魔法配置

然后我使用了这个应用程序。yaml文件,以使用此方法配置artemis连接,如Spring boot文档中所述。这在我的申请时也起到了作用。yaml文件包含以下配置:

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

这很有魅力。

Java配置的勇敢尝试。

因此,我选择了gold,并尝试了基于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控制台,我可以浏览消息并看到它们正在创建。但是,当我运行get on执行器健康时,我看到以下内容:

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

我想让我也试试吧。它表现出与上述相同的行为,还有一件有趣的事情。使用组织时。messaginghub。池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启动application.yaml配置的工作,但它限制了您在Camel上配置JMS客户端的方式。

共有1个答案

万嘉熙
2023-03-14

因此,经过一些挖掘和联系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;
    }
}
 类似资料:
  • 对于我一直在开发的一个微服务,我创建了一个自定义健康检查类,扩展了AbstractHealthIndicator,并能够在中获得输出 但当我向领事注册服务时,健康检查状态为失败。 尝试将执行器url配置为领事健康检查为spring。云领事发现健康检查url=http://localhost:8080/actuator/health。但它仍然失败,出现错误http://localhost:8566/

  • 我需要改变频率来检查springboot执行器中的DB运行状况。默认DB运行状况检查查询每毫秒执行一次。我想让这个查询每1分钟后执行一次,而不是毫秒。有什么方法可以自定义它吗?

  • 因此,我将Spring引导执行器添加到我的应用程序中,并在应用程序中指定。属性管理。endpoint。健康隐藏物生存时间=120秒,以缓存健康检查结果。因此,当我调用执行器/健康时,结果被缓存,效果很好。 当我调用执行器/健康/就绪或自定义创建的组时,问题开始出现。该请求结果不会被缓存。我查阅了Spring文档,只找到了主要健康终点的信息,没有找到特定人群的信息。 所以我的问题是:我错过了什么吗?

  • 在设置ELB健康检查的对话框中,它会声明: 如果实例未通过健康检查,它将自动从负载均衡器中删除。自定义健康检查以满足您的特定需要。 当健康检查失败时,将从ELB后面删除实例。我的问题是围绕“健康门槛”设置。当你悬停在帮助上时,它会说: 在声明EC2实例健康之前连续运行状况检查成功的次数。 如果实例声明为健康的,它是否被拉回负载平衡组?

  • 我有一个ECS集群,它有多个节点(任务定义),由应用程序负载平衡器前置。在负载平衡器和容器级别(在任务定义内)配置健康检查有意义吗? 负载平衡器对每个注册的目标运行配置的健康检查,以便注销故障节点。在容器级别设置健康检查可以完成相同的事情:ECS将注销任何未通过健康检查的容器(根据您的配置)。ECS将始终实例化更多任务定义实例,以满足您所需的计数。 对我来说,如果任务定义只有一个容器,那么只在负载

  • SOFABoot 为 Spring Boot 的健康检查能力增加了 Readiness Check 的能力。如果你需要使用 SOFA 中间件,那么建议使用 SOFABoot 的健康检查能力的扩展,来更优雅的上线应用实例 引入健康检查扩展 要引入 SOFABoot 的健康检查能力的扩展,只需要引入以下的 Starter 即可: <dependency> <groupId>com.alipay