SMALL

ActiveMQ란

간단하게 ActiveMQ는 메시지 브로커이다.

JMS를 지원한다( JMS: Java Message Service) ( JMS는 스펙이고, 그것을 구현해 좋은 제품이 ActiveMQ)

ActiveMQ를 사용하는 이유 

대부분의 동기식 통신 방식은 사용자로부터 받은 요청을 전부 처리할 때까지 Blocking 상태에 빠진다

요청을 모두 처리해야 사용자에게 응답을 줄 수 있다

하지만 메시지 큐 사용 시 요청을 큐에 넣고 Block상태에 빠지지 않고 응답을 줄 수 있다

후에 다른 서비스에서 큐에 쌓인 요청을 Consume 하여 요청을 처리할 수 있다

 

ActiveMQ 설치

 

https://activemq.apache.org/components/classic/download/ 

 

ActiveMQ

 

activemq.apache.org

다운로드한 파일을 unzip후에 bin폴더에 activemq 실행

 

 

ActiveMQ TCP prot : 61616

ActiveMQ WebConsole : http://127.0.0.1:8161 ( default user : admin / admin )

 

 

이제부터 실전 예제를 보자

예제로는 Product-Service와 Cart-Service가 존재한다

두 서비스 사이에 ActiveMQ를 두고

Product에서 ActiveMQ에 메시지를 produce 하고

Cart에서 ActiveMQ에 쌓인 메시지를 consume 한다.

ActiveMQ - Producer 

 

@RestController
@RequestMapping("/product")
@RequiredArgsConstructor
public class ProductController {

    private final ProductRepository productRepository;
    private final JmsTemplate jmsTemplate;
    private final ObjectMapper mapper;

    // get value from yaml file
    @Value("${product.jms.destination}")
    private String jmsQueue;

    @GetMapping("/sendToCart/{id}")
    public ResponseEntity<Product> sendToCart(@PathVariable long id) {
        Optional<Product> product = productRepository.findById(id);

        if (!product.isPresent()) {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }

        try {
            String jsonInString = mapper.writeValueAsString(product.get());

            jmsTemplate.convertAndSend(jmsQueue, jsonInString);

            return new ResponseEntity<>(product.get(), HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}

 

application.yml

server:
  port: 8045
spring:
  activemq:
    user: admin
    password: admin
    broker-url: tcp://localhost:61616
  application:
    name: product-service
product:
  jms:
    destination: product

ActiveMQ 설정 정보는 간단하다

  • ActiveMQ의 위치정보 (IP, Port)
  • ActiveMQ에 접근하기 위한 권한 정보

이외에 product.jms.destination은 특정값을 설정값으로 분리하여 관리하기 위해 임의로 추가한 값이다.

(코드에 해당 값을 String으로 선언해도 되지만, yml 설정으로 분리) 

 

 

ActiveMQ - Consumer

@Component
@RequiredArgsConstructor
@Slf4j
public class JmsConsumer {

    private final ProductRepository productRepository;
    private final ObjectMapper mapper;

    @JmsListener(destination = "${product.jms.destination}")
    public void consumeMessage(String data) {
        try {
            Product product = mapper.readValue(data, Product.class);

            log.info("data: {}", data);
            productRepository.save(product);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

application.yml

server:
  port: 8050
spring:
  application:
    name: cartservice
  activemq:
    user: admin
    password: admin
    broker-url: tcp://localhost:61616
product:
  jms:
    destination: product

 

참고&git

 

 

LIST

+ Recent posts