我有一个监控服务,可以在应用程序启动,应用程序关闭和每分钟(勾选)时向rabbitMQ发送消息。
启动和滴答事件工作正常。 当最初编写类时,关闭事件也起作用。
我使用的是spring-boot-starter-amqp 1.3.3.RELEASE
该事件是在DisposableBean
界面的ApplicationListener<ContextClosedEvent>
方法上触发的。
我也尝试过实现Lifecycle
接口和Lifecycle
接口
以上两种方法都返回:
java.lang.IllegalStateException:ApplicationContext已关闭 ConnectionFactory无法再创建连接。
我注意到有一个错误修复https://jira.spring.io/browse/AMQP-536建议使用monitorRabbitTemplate
界面。
如何确保在RabbitMQ连接关闭之前发送关闭事件消息?
编辑:更多信息和最新代码
应用程序有多个连接工厂到不同的服务器。 Monitor Service通过monitorRabbitTemplate
与RabbitMQ服务器连接。
问题似乎是MonitorService
连接工厂在Lifecycle
之前获得生命周期/关闭/处置事件。
最新代码(使用ApplicationListener<ContextClosedEvent>
代替DisposableBean
和@Component
public class MonitorServiceImpl implements MonitorService , Lifecycle {
private static final Logger LOGGER = LoggerFactory.getLogger(MonitorServiceImpl.class);
private final RabbitTemplate monitorRabbitTemplate;
private final String queueName;
private final Gson gson = new Gson();
@Autowired
public MonitorServiceImpl(@Qualifier("monitorRabbitTemplate") final RabbitTemplate monitorRabbitTemplate,
@Value("${monitor.rabbitmq.queue.name:monitor}") final String queueName) {
this.monitorRabbitTemplate = monitorRabbitTemplate;
this.queueName = queueName;
}
@Scheduled(fixedDelay = 60000)
public void tick() {
try {
send(new Monitor(Status.INFO, "I am here"));
} catch (final Exception e) {
LOGGER.error("FAILED TO SEND TICK EVENT", e);
}
}
@Override
public void send(final Monitor monitor) {
try {
final Message message = MessageBuilder.withBody(gson.toJson(monitor).getBytes())
.setContentType("application/json").setPriority(0).setDeliveryMode(MessageDeliveryMode.PERSISTENT)
.build();
monitorRabbitTemplate.send(queueName, message);
} catch (final Exception e) {
LOGGER.error("FAILED TO SEND MONITOR EVENT", e);
LOGGER.error("FAILED TO SEND MONITOR EVENT to {}:{}", monitorRabbitTemplate.getConnectionFactory()
.getHost(), monitorRabbitTemplate.getConnectionFactory().getPort());
}
}
@Override
public void start() {
try {
send(new Monitor(Status.STARTING, "Application starting up..."));
} catch (final Exception e) {
LOGGER.error("FAILED TO SEND STARTUP EVENT", e);
}
}
@Override
public void stop() {
try {
send(new Monitor(Status.TERMINATING, "Application shutdown..."));
} catch (final Exception e) {
LOGGER.error("FAILED TO SEND SHUTDOWN EVENT", e);
}
}
@Override
public boolean isRunning() {
return true;
}
}
):
<div id="parent">
<div class="row">
<div class="col-md-6 col-xs-6" >
<div>
<img src="img/picture1.jpg" alt="pic1">
</div>
<div class="col-md-6 col-xs-6">
<div>
<img src="img/temp/picture2.jpg" alt="pic2">
</div>
</div>
</div>
</div>
答案 0 :(得分:2)
也许你可以分享一些代码/构建配置?因为听ContextClosedEvent
和实施Lifecycle
都适合我。
这是我的申请:
@SpringBootApplication
public class SpringRabbitmqDemoApplication {
@Component
public static class Whatever implements Lifecycle {
private final RabbitTemplate template;
@Autowired
public Whatever(RabbitTemplate template) {
this.template = template;
}
@EventListener
public void event(ContextClosedEvent event) throws Exception {
sendMessage(event.toString());
}
private void sendMessage(String message) {
template.convertAndSend("", "queue", message);
System.out.println("Sent event " + message);
}
@Override
public void start() {
sendMessage("start");
}
@Override
public void stop() {
sendMessage("stop");
}
@Override
public boolean isRunning() {
return true;
}
}
public static void main(String[] args) {
SpringApplication.run(SpringRabbitmqDemoApplication.class, args);
}
}
我的pom.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>spring-rabbitmq-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-rabbitmq-demo</name>
<description>Demo project for Spring Boot RabbitMQ</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
这是我得到的输出:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.3.3.RELEASE)
2016-07-21 17:45:24.984 INFO 77845 --- [ main] c.example.SpringRabbitmqDemoApplication : Starting SpringRabbitmqDemoApplication on mmilivojevic-hal9000 with PID 77845 (started by mmilivojevic in /Volumes/Macintosh HD/springrabbitmqdemo)
2016-07-21 17:45:24.990 INFO 77845 --- [ main] c.example.SpringRabbitmqDemoApplication : No active profile set, falling back to default profiles: default
2016-07-21 17:45:25.092 INFO 77845 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@27d415d9: startup date [Thu Jul 21 17:45:25 CEST 2016]; root of context hierarchy
2016-07-21 17:45:26.746 INFO 77845 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.amqp.rabbit.annotation.RabbitBootstrapConfiguration' of type [class org.springframework.amqp.rabbit.annotation.RabbitBootstrapConfiguration$$EnhancerBySpringCGLIB$$2cf55fc7] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2016-07-21 17:45:27.620 INFO 77845 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2016-07-21 17:45:27.636 INFO 77845 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase -2147482648
2016-07-21 17:45:27.637 INFO 77845 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147483647
2016-07-21 17:45:27.661 INFO 77845 --- [ main] c.example.SpringRabbitmqDemoApplication : Started SpringRabbitmqDemoApplication in 3.456 seconds (JVM running for 4.288)
2016-07-21 17:45:27.662 INFO 77845 --- [ Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@27d415d9: startup date [Thu Jul 21 17:45:25 CEST 2016]; root of context hierarchy
2016-07-21 17:45:27.785 INFO 77845 --- [ Thread-1] o.s.a.r.c.CachingConnectionFactory : Created new connection: SimpleConnection@7ff53a50 [delegate=amqp://guest@127.0.0.1:5672/]
Sent event org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@27d415d9: startup date [Thu Jul 21 17:45:25 CEST 2016]; root of context hierarchy]
2016-07-21 17:45:27.829 INFO 77845 --- [ Thread-1] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase 2147483647
2016-07-21 17:45:27.830 INFO 77845 --- [ Thread-1] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase 0
Sent event stop
2016-07-21 17:45:27.831 INFO 77845 --- [ Thread-1] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase -2147482648
2016-07-21 17:45:27.834 INFO 77845 --- [ Thread-1] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown