ActiveMQ란
간단하게 ActiveMQ는 메시지 브로커이다.
JMS를 지원한다( JMS: Java Message Service) ( JMS는 스펙이고, 그것을 구현해 좋은 제품이 ActiveMQ)
ActiveMQ를 사용하는 이유
대부분의 동기식 통신 방식은 사용자로부터 받은 요청을 전부 처리할 때까지 Blocking 상태에 빠진다
요청을 모두 처리해야 사용자에게 응답을 줄 수 있다
하지만 메시지 큐 사용 시 요청을 큐에 넣고 Block상태에 빠지지 않고 응답을 줄 수 있다
후에 다른 서비스에서 큐에 쌓인 요청을 Consume 하여 요청을 처리할 수 있다
ActiveMQ 설치
https://activemq.apache.org/components/classic/download/
다운로드한 파일을 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
'Spring > spring-cloud' 카테고리의 다른 글
[Spring] Spring Cloud Netflix Eureka 사용해보기 (0) | 2022.04.15 |
---|---|
[Spring] Spring Cloud Gateway(SCG) 사용해보기 (0) | 2022.04.12 |
[Spring] Spring Cloud Config-Asymmetric Key Encryption(비대칭키 암호화) (0) | 2022.01.05 |
[Spring] Spring Cloud Config-Symmetric Key Encryption(대칭키 암호화) (0) | 2022.01.03 |
[Spring] Exception 처리(@ControllerAdvice, @ExceptionHandler, @RestControllerAdvice) (0) | 2021.12.29 |