이번 글에서는 Spring Boot를 사용한 Message Reqeust/Reply에 대해 알아보도록 하겠습니다. 1. Request/Reply Request는 message 처리 요청을 의미합니다. Reply는 메세지 처리후의 응답이라고 생각할 수 있습니다. 기본적으로 Consumer는 RabbitMQ로 부터 메세지 처리 요청(Request)이 오면 적절한 프로세스를 통해 메세지를 처리하는 과정을 거치게 됩니다. 처리과정을 거친뒤에는 해당 Consumer에서 아래 그림처럼 다른 서비스의 API를 호출해 또다른 프로세스를 진행할 수 있습니다. 아니면 아래 그림처럼 또다른 메세지를 생성해 적절한 Exchnage로 메세지를 전달 할 수 있습니다. 만약 위처럼 메시지를 또다른 exchnage에 전달하려고하면 ..
이번 글에서는 RabbitMQ의 Message Order와 Multiple Message Type을 다루는 방법에 대해 알아보도록 하겠습니다. 1. Message Order Message Order는 Queue에 들어온 메시지가 처리되는 순서를 의미합니다. 만약 순서대로 처리되어야 되는 메시지가 Queue에 들어올 경우 Message Order는 반드시 지켜져야 합니다. 😅 1-1) One Queue + One Consumer 기본적으로 하나의 Queue에 하나의 Consumer만 존재할 경우에는, RabbitMQ는 메세지 처리순서를 보장합니다. 1-2) One Queue + Multiple Consumer 만약 하나의 Queue에 여러 Consumer가 존재하고, 각각의 Consumer들의 메시지 처리..
이번 글에서는 RabbitMQ의 Prefetch에 대해 알아보겠습니다. 1. Prefetch란? Queue의 메세지를 Consumer의 메모리에 쌓아놓을 수 있는 최대 메세지의 양 입니다. 예를 들어 Prefetch가 250일 경우, RabbitMQ는 250개의 메세지까지 한번에 Listener의 메모리에 Push합니다. 그뒤 Consumer는 메모리에서 하나씩 메세지를 꺼내서 처리하게 됩니다. 이러한 Prefetch 값은 각 어플리케이션 환경에 맞도록 조정할 필요가 있습니다. 예를 들어 아래의 그림에서 총 500개의 메세지가 발행됬다고 가정해보겠습니다. 이후 Prefetch가 250인 Consumer1과 Consumer2가 각각 250개씩 본인들의 메모리에 메시지를 가져갑니다. 그뒤 각각의 Consum..
이번 글에서는 Spring Boot의 @Scheduled를 사용해 Consumer를 ON/OFF 해보도록 하겠습니다. 1. @Scheduled 먼저 spring boot에서 사용할 수 있는 @Scheduled의 종류를 살펴보겠습니다. 1-1) @Scheduled(fixedDelay = N) 이전 execution으로부터의 delay 시간을 의미합니다. 예를 들어 다음 execution이 실행되는 시간은 이전 execution이 완료된 후 N 시간이 지난이후입니다. 1-2) @Scheduled(fixedRate = N) 어플리케이션이 실행된후 매 N 시간마다 execution을 실행합니다. 예를 들어 0초에 이전 execution이 실행되었다면 0+N 시간 후 다음 execution이 실행됩니다. 1-3)..
이번 글에서는 Spring Boot의 Jackson2JsonMessageConverter를 사용해 손쉽게 Object를 JSON Message Format으로 변경해보겠습니다. 1. Message Converter란? object를 rabbitmq의 message 형식으로 변환해주는 것을 의미합니다. 이전글까지는 Rabbitmq를 통해 메세지를 주고받기 위해, object들을 string 형식으로 변환해야하는 번거로움이 있었습니다. 메세지를 전달할 때 사용하는 RabbitTemplate의 default message convertor(SimpleMessageConverter)가 input data type으로 string을 받기때문입니다. 따라서 아래와 같이 ObjectMapper를 사용해서 object..
이번 글에서는 Java Code로 RabbitMQ Structure를 생성해보겠습니다. 0. RabbitMQ Structure란? Exchange, Queue, Binding 등의 RabbitMQ Server의 구조를 의미합니다. rabbitmq의 structure는 rabbitmq managemenet console에서 GUI를 통해 생성할 수도 있지만, Java code 내부에서도 생성해 사용할 수 있습니다. rabbitmq management console 1. @Configuration Java Code로 RabbitMQ Structure를 생성하기 위해선 config 파일을 생성해야 합니다. 아래와 같이 @Configuration 어노테이션을 선언한 config 파일을 생성합니다. @Config..
이번 글에서는 대표적인 오픈소스 메세지 시스템인 RabbitMQ와 Kafka를 비교해보겠습니다. 1. Message Retention Kafka : by policy Kafka의 메세지 보유기간은 policy에 기반합니다. 설정한 policy 기간 동안에는 메시지가 소멸되지 않습니다. 따라서 동일한 메세지를 반복적으로 처리할 수 있습니다. RabbitMQ : by acknowledge RabbitMQ의 메세지 보유기간은 acknowledge에 기반합니다. ack를 받은 메세지는 사라지게 됩니다. 따라서 처리를 완료한 메세지를 재 처리하고 싶을 경우에는 반드시 producer가 동일한 메세지를 re-publish 해야합니다. 2. Message Routing Kafka : no routing mechani..
이번 글에서는 Spring Boot의 RabbitMQ Retry mechanism에 대해 알아보겠습니다. 0. Retry Mechanism이란? 메시지 처리에 실패했을때 실패한 메시지에 대한 error handling 방법을 구조화한 structure 입니다. 이전 retry mechanism 글(https://velog.io/@minholee_93/RabbitMQ-Retry-Mechanism-nik4tel6hs) 에서는 wait exchange와 retry exchange를 직접 구현해 아래와 같은 구조로 retry mechanism을 설계했었습니다. 하지만, Spring boot에서 제공해주는 기능을 사용하면 wait/retry 없이 간단한 구조로 retry mechanism을 구현할 수 있습니다. ..
이번 글에서는 RabbitMQ Administartion API를 사용해 주기적으로 Dirty Queue를 체크해보겠습니다. 0. Dirty Queue란? Queue 내부에 메시지가 남아있는 Queue를 의미합니다. 일반적인 경우에, 정상적으로 Consumer 들이 Queue의 메세지를 적절히 처리하고 있다면 Queue 내부에 메세지가 쌓여 있지 않습니다. (물론 prefetch 를 낮게 잡았다면 메세지는 consumer의 메모리가 아닌 Queue 내부에서 process를 기다릴 수 있습니다.) 따라서 Queue 내부에 메세지가 대량으로 쌓여있을 경우에는, 무엇인가 잘못되었을 확률이 있습니다. 이를 체크하고 대응하기위해서는 주기적으로 (예를들면 매일 자정) Dirty Queue를 확인한 후 적절한 대응이..
이번 글에서는 Publisher API를 사용해 RabbitMQ에 메세지를 Publish 해보겠습니다. 0. Publisher API를 사용하는이유? RabbtiMQ로 메세지를 Publish 하기전 메세지의 Validation을 check 하기위해 사용합니다. 아래 그림과 같이 기업에서는 무수히 많은 어플리케이션이 RabbitMQ Message Server를 통해 메세지를 주고받습니다. 때문에 통합된 규격의 메세지 Validation을 활용할 필요가 있습니다. 따라서 모든 메세지는 RabbitMQ 서버에 Publish 하기전에 Validation API를 거치도록 구현해야 합니다. 이를 Publisher API라고 하며 Spring Boot에서는 RestController의 PostMapping으로 구현..
이번 글에서는 RabbitMQ의 Wait Queue와 Dead Queue를 사용한 메세지 처리 Retry mechanism에 대해 알아보겠습니다. 0. Retry Mechanism이란? 메시지 처리에 실패했을때 실패한 메시지에 대한 error handling 방법을 구조화한 structure 입니다. 이전 글에서 처리에 실패한 메시지는 DLX(Dead Letter Exchnage)로 보내어 적절한 error handling 과정을 거쳐야된다고 말씀드렸습니다. 이를 좀더 구체화하면 아래 그림과 같은 Retry Mechanism으로 표현할 수 있습니다. ✔ Retry Mechanism 0. "work exchnage"에서 "work queue"로 메시지를 전달한다. "work queue" 에서 메시지를 처리..
이번 글에서는 RabbitMQ의 Dead Letter Exchange와 TTL(Time to Live)에 대해 알아보겠습니다. 1. Dead Letter Exchnage란? 처리할 수 없는 Message를 전달할 Exchange입니다. 기본적으로 RabbitMQ의 메세지가 예상치 못한 error로 인해 처리될 수 없을 경우 다시 Queue로 돌아가는 requeuing을 수행하게 됩니다. 하지만, 수차례 동일한 에러로 인해 해당 메시지를 처리할 수 없을 경우에도 이 메세지는 무한히 Queue에 담겨있게 됩니다. 마찬가지로 동일한 에러가 무한히 발생하게 됩니다. 이를 방지하고자 특정 횟수 이상의 error가 발생한 메세지는 Dead Letter Exchange로 보내 적절한 error handling 과정을..
이번 글에서는 RabbitMQ의 메세지 broker인 Exchange에 대해 알아보겠습니다. 0. Exchange란? 메세지의 Routing Key에 따라 메세지를 적절한 Queue에 분배하는 broker 역할을 수행하는 Distributer 입니다. Exchange의 종류에는 Fanout / Direct / Topic 등이 있습니다. 1. Fanout Exchange Fanout Exchange는 binding된 모든 Queue에 하나의 메시지를 복제해 내보냅니다. 만약 아래의 그림처럼, HR 시스템이 "x.hr" Exchange로 신규 입사자 정보를 Publish 하면 Fanout Exchange는 해당 메세지를 복제해 "q.hr.accounting"과 "q.hr.marketing"으로 전달합니다. ..
이번 글에서는 RabbitMQ에서 사용하는 JSON Message Format을 Customize 해보도록 하겠습니다. 1. Customize JSON Format 앞선 글에선 Jackson의 ObjectMapper를 사용해 Employee Entity를 JSON String 형식으로 변경할 수 있었습니다. Employee @Getter @Setter @AllArgsConstructor @NoArgsConstructor public class Employee { private String employeeId; private String name; private LocalDate birthDate; } 기본적으로 Jackson은 Default로 구현되어있는 serialize() 메서드를 참고해 아래와 같이..
이번 글에서는 RabbitMQ에서 사용하는 메세지 포맷인 JSON에 대해 알아보도록 하겠습니다. 0. 왜 JSON을 사용하는가? RabbitMQ는 메세지 Format으로 어떠한 String 형식도 허용합니다. 하지만 이러한 자유도 때문에 오히려 Publisher와 Consumer 사이에 불필요한 자원을 낭비하게 됩니다. 만약 특정 Publihser가 본인만 사용하는 Format으로 Message를 발행할 경우, Consumer는 해당 Message Format을 해석해 사용하기 위한 비용을 소모해야 합니다. 따라서 이러한 낭비를 막고, 비즈니스 로직에 더욱 집중하기 위해 가장 보편적이로 널리 쓰이는 JSON Format으로 메시지 규격을 통일하는 것 입니다. JSON은 대부분의 언어에서 Create 및 ..
이번 글에서는 하나의 이상의 Consumer를 등록해 Queue에 발행된 메세지를 소비해보도록 하겠습니다. 1. 언제 Multiple Consumer를 사용하는가? Multiple Consumer는 Producer의 메시지 발행속도가 Subscriber의 Consume 속도보다 빠를 때 빠른 메세지의 처리를 위해 사용합니다. 예를 들어 아래 그림과 같이 Producer는 0.5s 마다 메세지를 발행하고, Consumer는 1.5s마다 하나씩 메시지를 처리한다면 시간이 지날 수록 Queue에는 처리되지 못한 메세지가 점점 쌓이게 됩니다. 따라서 1개 이상의 Consumer를 사용해 메세지를 보다 빠른속도로 처리함으로써 이와 같은 문제점을 개선할 수 있습니다. 쌓여있는 숙제를 여러명이서 나눠 빨리빨리 처리한..
이번 글에서는 Spring boot의 Scheduling 기능을 사용해보도록 하겠습니다. 1. Fixed Rate 주기적로 메세지를 생성하기 위해선 Fixed Rate를 사용합니다. 1-1) Producer @Service public class RabbitmqProducer { @Autowired private RabbitTemplate rabbitTemplate; private Logger log = LoggerFactory.getLogger(RabbitmqProducer.class) ; private int i = 0; @Scheduled(fixedRate = 1000) public void sendMessage(){ i++; rabbitTemplate.convertAndSend("q.minho",..
이번 글에서는 Spring boot에서 RabbitMQ를 사용하는 기본적인 방법에 대해 알아보겠습니다. 0. RabbitMQ 설치하기 먼저 아래 링크를 참고해 각자의 서버에 RabbitMQ 서버와 RabbitMQ-Management를 설치합니다. 저는 AWS EC2 서버에 Docker를 사용해 RabbitMQ를 설치했습니다. ✔ EC2에 Docker 설치법 https://hackernoon.com/running-docker-on-aws-ec2-83a14b780c56 ✔ RabbitMQ Docker 설치법 https://psychoria.tistory.com/541 RabbitMQ Instance 작명규칙은 아래와 같습니다. ✔ Naming Rule • lowercase • Exchange : "x.[na..
이번 글에서는 RabbitMQ, Kafka 같은 메세지 시스템을 사용하는 이유에 대해 알아보겠습니다. 0. Message System이란? Application간 메세지를 주고받는 Communication Mechanism을 의미합니다. 주로 사용되는 메세징 시스템에는 RabbitMQ와 Kafka 등이 있습니다. 1. Message System이 없다면? 대규모 Enterprise 환경에서 만약 메시지 시스템을 사용하지 않고 구현한다면 아래와 같은 문제점이 발생하게됩니다. ✔ Real-Time 어플리케이션 구현이 어렵습니다. 만약 아래와 같이 3개의 독립된 어플리케이션(HR, Marketing, Directory) 이 존재할 때, 메시지 시스템이 없다면 각 시스템의 정보를 가져오기위해선 특정 시간별 Pu..