2016-07-18 3 views
4

응용 프로그램 시작, 응용 프로그램 종료 및 모든 분 (틱)에 대해 rabbitMQ에 메시지를 보내는 모니터 서비스가 있습니다.Spring 응용 프로그램 종료시 RabbitMQ 메시지 보내기

시작 및 틱 이벤트가 정상적으로 작동합니다. 클래스가 원래 작성되었을 때 시스템 종료 이벤트도 작동했습니다. 내가 사용하고

스프링 부팅 스타터 AMQP 이벤트가 DisposableBean 인터페이스의 destroy 방법에 해고되었다

1.3.3.RELEASE.

나는 또한 ApplicationListener<ContextClosedEvent> 인터페이스와 Lifecycle 인터페이스를 구현하는 시도

모두 위의 방법은 반환 :

java.lang.IllegalStateException : ApplicationContext를 폐쇄하고 ConnectionFactory에 더 이상 연결을 만들 수 없습니다.

나는 Lifecycle 인터페이스를 제안하는 https://jira.spring.io/browse/AMQP-536 버그 수정이 있음을 발견했습니다.

RabbitMQ 연결이 종료되기 전에 종료 이벤트 메시지를 보내려면 어떻게해야합니까?

편집 : 더 많은 정보와 최신 코드

응용 프로그램은 서로 다른 서버에 여러 연결 팩토리를 가지고있다. 모니터 서비스는 monitorRabbitTemplate을 통해 RabbitMQ 서버와 연결됩니다.

MonitorService 전에 문제가 monitorRabbitTemplate 연결 팩토리에있는 것 같습니다. 수명주기/종료/폐기 이벤트가 발생합니다.

최신 코드 (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; 
    } 
} 

답변

2

은 어쩌면 당신은 구성을 빌드/몇 가지 코드를 공유 할 수 있을까? ContextClosedEvent을 듣고 Lifecycle을 구현하면 둘 다 저에게 효과적입니다.

. ____   _   __ _ _ 
/\\/___'_ __ _ _(_)_ __ __ _ \ \ \ \ 
(()\___ | '_ | '_| | '_ \/ _` | \ \ \ \ 
\\/ ___)| |_)| | | | | || (_| | )))) 
    ' |____| .__|_| |_|_| |_\__, |//// 
=========|_|==============|___/=/_/_/_/ 
:: 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.spring[email protected]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.spring[email protected]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: [email protected] [delegate=amqp://[email protected]:5672/] 
Sent event org.springframework.context.event.ContextClosedEvent[source=org.spring[email protected]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 
: 여기
<?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> 

내가 얻을 출력입니다 :

@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 파일 : 여기

내 응용 프로그램입니다
관련 문제