我正在使用带有驼峰和ActiveMQ的spring-boot。
我正在通过@EnableJms注释使用activemq自动配置。 但是创建我自己的ActiveMQComponent以在所有队列上启用“事务(true)”。
@Bean(name = "activemq")
@ConditionalOnClass(ActiveMQComponent.class)
public ActiveMQComponent activeMQComponent(ConnectionFactory connectionFactory) {
ActiveMQComponent activeMQComponent = new ActiveMQComponent();
activeMQComponent.setConnectionFactory(connectionFactory);
activeMQComponent.setTransacted(true);
activeMQComponent.setTransactionManager(jmsTransactionManager(connectionFactory));
return activeMQComponent;
}
它运行良好,但是当我尝试优雅地关闭应用程序时。 在骆驼正常关闭发生之前,PooledConnectionFactory会被破坏。
导致大量错误并且路线无法正确停止。
像这个错误的20倍:
2017-05-04 18:21:59.748 WARN 12188 --- [er[test.queue]] o.a.activemq.jms.pool.PooledSession : Caught exception trying rollback() when putting session back into the pool, will invalidate. javax.jms.IllegalStateException: The Session is closed
其次是:
2017-05-04 18:21:59.748 INFO 12188 --- [ Thread-18] o.a.camel.spring.SpringCamelContext : Apache Camel 2.18.3 (CamelContext: route) is shutting down
然后:
2017-05-04 18:21:59.766 INFO 12188 --- [ - ShutdownTask] o.a.camel.impl.DefaultShutdownStrategy : Waiting as there are still 1 inflight and pending exchanges to complete, timeout in 300 seconds. Inflights per route: [test2 = 1]
任何人都可以帮我配置spring-boot camel activemq以及正常关机吗?
由于
更新 以下是我的pom.xml示例:
<properties>
<!-- Spring -->
<spring-boot.version>1.4.3.RELEASE</spring-boot.version>
<!-- Camel -->
<camel-spring-boot.version>2.18.3</camel-spring-boot.version>
</properties>
....
<!-- Camel BOM -->
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-boot-dependencies</artifactId>
<version>${camel-spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
...
<!-- Spring -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<!-- ActiveMQ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-camel</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
</dependency>
<!-- Camel -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
</dependency>
更新2: 在进一步调查和创建一个新项目之后逐一添加每个修改我已经解决了这个问题。
关闭工作正常,直到我添加特定端点:
@EndpointInject(uri = "direct:aaa")
private Endpoint errorHandling;
使用:
private String errorHandling = "direct:aaa";
不会产生错误。
似乎使用@EndpointInject使activemq先关闭
更新3:
发现SpringCamelContext没有实现ApplicationListener,因此它的方法“onApplicationEvent”不会被称为处理camel的“shutdownEager”。
答案 0 :(得分:0)
重要的是使用Camel Spring Boot Starter。
http://camel.apache.org/spring-boot.html
如何在Spring Boot应用程序中启用Camel自动配置?
将camel-spring-boot jar放入类路径中:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-spring-boot</artifactId> <version>${camel.version}</version> <!-- use the same version as your Camel core version --> </dependency>
camel-spring-boot jar附带了spring.factories文件,因此只要将该依赖项添加到类路径中,Spring Boot就会自动为您自动配置Camel。好极了!那很快;)。
自动配置的Camel上下文
Camel自动配置提供的最重要的功能是CamelContext实例。
Camel自动配置为您创建SpringCamelContext,并负责正确初始化和关闭该上下文。
创建的Camel上下文也在Spring应用程序上下文中注册(在camelContext bean名称下),因此您可以像访问任何其他Spring bean一样访问它。
@Configuration
public class MyAppConfig {
@Autowired
CamelContext camelContext;
@Bean
MyService myService() {
return new DefaultMyService(camelContext);
}
}
答案 1 :(得分:0)
显然是https://issues.apache.org/jira/browse/CAMEL-2607 SpringCamelContext不再实现ApplicationListener接口。
由于我使用的是spring-boot自动配置,因此我没有使用添加侦听器的CamelContextFactoryBean。
有一个临时修复,我创建了一个监听ApplicationEvent并将它们分派给SpringCamelContext方法的组件:
public class SpringCamelContextFix implements ApplicationListener<ApplicationEvent> {
private SpringCamelContext camelContext;
public SpringCamelContextFix(SpringCamelContext camelContext) {
this.camelContext = camelContext;
}
@Override
public void onApplicationEvent(ApplicationEvent event) {
camelContext.onApplicationEvent(event);
}
}
答案 2 :(得分:0)
我在使用Spring Boot,ActiveMQ或A-MQ和Camel(版本2.18.1.redhat-000012)运行单元/集成测试时遇到了同样的问题。显然,当Spring Boot关闭时,JMS线程池在Camel上下文关闭之前关闭,这是错误的顺序。 @John D在Camel users mailing list thread中提供了一个代码修复程序,与他在此主题中提供的内容类似。这是John D代码的版本,对我有用:
@Component
public class SpringCamelContextFix implements
ApplicationListener<ApplicationEvent> {
@Inject
private SpringCamelContext camelContext;
public SpringCamelContextFix(SpringCamelContext camelContext) {
this.camelContext = camelContext;
}
@Override
public void onApplicationEvent(ApplicationEvent event) {
camelContext.onApplicationEvent(event);
}
}