Send RabbitMQ Message to Spring Shutting Down the Application

I have a monitoring service that sends a rabbitMQ message when the application starts, the application terminates, and every minute (tick).

Start and tick events work fine. When the class was originally written, the shutdown event also worked.

I am using spring-boot-starter-amqp 1.3.3.RELEASE

The event was fired using an destroyinterface method DisposableBean.

I also tried to implement the interface ApplicationListener<ContextClosedEvent>and Lifecycleinterface

Both of the above methods return:

java.lang.IllegalStateException: ApplicationContext is closed and ConnectionFactory can no longer create connections.

I noticed that the bug https://jira.spring.io/browse/AMQP-536 , which offers an interface , has been fixed Lifecycle.

How do I ensure that my disconnect event message is sent before the RabbitMQ connection is closed?

EDIT: More Information and Latest Code

The application has several factories connecting to various servers. The monitoring service connects to the RabbitMQ server through monitorRabbitTemplate.

The problem is that the monitorRabbitTemplateFactory connection receives the Lifecycle / Shutdown / Dispose event before MonitorService.

Last code (using Lifecycleinstead of ApplicationListener<ContextClosedEvent>and 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;
    }
}
+4
source share
1

, /? 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
+2

Source: https://habr.com/ru/post/1648270/


All Articles