복붙노트

[SPRING] Spring 부트 - 별도의 서비스로 임베디드 JMS 브로커 공유

SPRING

Spring 부트 - 별도의 서비스로 임베디드 JMS 브로커 공유

ActiveMQ를 통해 서로 통신해야하는 두 가지 서비스가 있습니다. 하나의 서비스에 수신자와 발신자가있을 때 모든 것이 잘 작동하지만 분리하면 이상한 activemq 예외가 발생합니다.

이것은 서비스 A의 구성입니다.

@EnableScheduling
@SpringBootApplication
@EnableJms
public class App extends SpringBootServletInitializer {

  private static final Logger log = LoggerFactory.getLogger(App.class);

  @Autowired
  private static JmsTemplate jms;

  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }

}

메시지 보내기 :

  @Autowired
  private JmsTemplate jms;

  public void sendTicket(Reservation reservation) {
    log.debug("---------------sending message----------------");
    // Send a message
    jms.send("mailbox-destination", new MessageCreator() {
      public ObjectMessage createMessage(Session session) throws JMSException {
        ObjectMessage message = session.createObjectMessage();
        message.setObject(reservation);
        return message;
      }
    });
  }

JMS가 인 메모리 대기열로 구성되었습니다.

spring.activemq.in-memory=true
spring.activemq.pooled=false

서비스 B도 비슷하지만 id는 JmsContainerFactory를 정의하지 않습니다. 수신기 만 있습니다 :

@Component
public class Receiver {

  private static final Logger log = LoggerFactory.getLogger(Receiver.class);

  /**
   * Receive a message with reservation and print it out as a e-ticket.
   * 
   * @param reservation
   */
  @JmsListener(destination = "mailbox-destination")
  public void receiveMessage(Reservation reservation) {
    log.info("Received <" + reservation.getId() + ">");
  }
}

서비스 A에는 JMS 및 ActiveMQ 브로커가 종속 관계로 있습니다.

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-broker</artifactId>
        </dependency>

서비스 B에는 JMS 종속성 만 있습니다.

두 서비스 사이에서 빈을 공유하고 그들간에 메시지를 보내는 방법을 알려 주실 수 있습니까? 나는이 주제에 대해 완전히 새로운 것이다.

메시지를받을 때 다음 예외가 발생합니다.

org.springframework.jms.UncategorizedJmsException: Uncategorized exception occured during JMS processing; nested exception is javax.jms.JMSException: Could not create Transport. Reason: javax.management.InstanceAlreadyExistsException: org.apache.activemq:type=Broker,brokerName=localhost

편집 : 서비스 중 하나에서 브로커 종속성을 제거하면 Tomcat이 시작되지 않습니다.

java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost]]
    at java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.util.concurrent.FutureTask.get(FutureTask.java:192)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:917)
    at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.StandardService.startInternal(StandardService.java:439)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:769)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:625)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:351)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:485)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost]]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1399)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.catalina.LifecycleException: A child container failed during start
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:925)
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:871)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    ... 6 common frames omitted

해결법

  1. ==============================

    1.JMS 서버는 역사적으로 독립적으로 독립 실행 형 응용 프로그램이었으며 메시지의 소비자 및 수신기는이 서버와 통신했습니다. 따라서 일반적으로 JMS 방정식에는 세 개의 개별 응용 프로그램이 있습니다.

    JMS 서버는 역사적으로 독립적으로 독립 실행 형 응용 프로그램이었으며 메시지의 소비자 및 수신기는이 서버와 통신했습니다. 따라서 일반적으로 JMS 방정식에는 세 개의 개별 응용 프로그램이 있습니다.

    이제 스프링 부트는 액티브 MQ JMS 브로커 (JMS 서버)를 스프링 부트 애플리케이션에 임베드 할 수있게 해줍니다. 그러나 자체적 인 임베디드 JMS 브로커가있는 각각의 Spring 부트 서비스를 구성하는 경우이 두 JMS 브로커는 완전히 별개이며 서로에 대해 모르고 어떤 방식으로도 연결되지 않습니다.

    프로덕션 환경에서 JMS를 사용하려면 Spring 부트 임베디드 JMS 브로커를 사용하지 않고 별도로 호스트하는 것이 훨씬 현명합니다. 따라서 3 노드 설정이 PROD에 대해 선호됩니다.

    편집하다:

    임베디드 JMS 중개인을 공유하는 이전 방법으로 잘못 생각한 것 같습니다. Spring Docs를 살펴보면 ActiveMQ에서는 불가능한 것처럼 보입니다.

    나는 Spring Enterprise 예제에서 작업 할 때 HornetQ로 시도했지만, 지금은 그런 설정을 찾을 수 없습니다. 그래서 문제가 있었고 별도의 세 번째 노드를 사용하게되었습니다.

    너가 그것을 더 시험하고 싶으면, 나는

    그러나 내가 언급했듯이, 나는 이것이 가능하기 전에 이것을 제대로 작동시키지 못했고 확실하지도 않았다. Spring Boot docs에서이 조합으로 작동하지 않는다는 명시적인 메시지를 찾지 못했습니다.

    필자는 스프링 부트 JMS 브로커가 내장 된 아이디어가 외부 세계에 임베디드 JMS 중개인을 노출시키지 않고 메모리 통합 테스트에만 사용할 수 있다고 생각한다.

  2. from https://stackoverflow.com/questions/34607596/spring-boot-sharing-embedded-jms-broker-with-separate-service by cc-by-sa and MIT license