ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RabbitMQ 와 Kafka
    공부방 2024. 7. 12. 22:16

    메시지 브로커

    개인 프로젝트를 진행하던 중, 이메일을 보내는 기능을 구현하고자했다.

    시스템 구성은 API 서버가 있고 이 서버에서 메일을 보내고자할경우 별도의 Mail 서버로 요청을 보내 메일을 보내는것이다. 

    간단하게 API 서버에서 Mail 서버로 HTTP를 사용해 API 요청을 보내 처리해도 되지만 이럴경우 두 서버간의 요청이 동기적으로 처리되어버린다.

    메일을 보내는 기능 자체는 사용자의 요청에 즉각적으로 처리가 될 필요 없는 기능이다. 이 때문에 나는 비동기적으로 처리하는 방법으로 구조를 잡았다. 메시지 브로커를 이용하여 메일 서버와 통신하는것이다. 이렇게되면 API 서버는 메일을 보내는 요청을 메시지 브로커에 던지면 끝이다. 그 뒤는 메일서버가 처리할 영역으로 두 서버의 역할이 확실히 분리된다.

    출처 - Better Programming

    메시지 브로커는 메시징 미들웨어 또는 메시지 지향 미들웨어(MOM) 솔루션 내의 소프트웨어 모듈입니다.  -IBM

    메시지 브로커를 설명하는 그림과 그림이다. 좌측은 브로커가 없을경우 통신하는 방법이다. 각각의 서비스가 직접적으로 연결되어있다. 서비스 수가 많아진다면 복잡도는 계속 증가할것이다.

    우측은 메시지 브로커를 도입한 구성도이다. 우체통을 생각하면 쉽다. 각각의 서비스들은 메시지를 보낸다면 우체통에 넣어두면된다. 만약 자신의 우체통에 누가 메시지를 넣어두었다면 가져가서 처리하면된다. 이처럼 중앙화돼 관리되다보니 서비스가 늘어나도 복잡도가 크게 늘어나지 않는다. 이런 메시지를 발행하는 서비스를 프로듀서, 메시지를 읽는 서비스를 컨슈머라고 한다. 

    어떤 서비스가 메시지 브로커를 사용하면 좋을까

    1. 이런 메시지 브로커를 사용하는 서비스는 즉각적인 응답이 필요할경우 맞지않다. 각 서비스간 안전하게 메시지를 전달하고자 할 경우 적합하다.

    2. 노드간의 독립성을 확보하고자하는 서비스에 적합하다.

    3. 확장성을 많이 필요로 하는 경우 적합하다.

    RabbitMQ 와 Kafka

    이런 메시지브로커형식은 크게 두가지로 나뉜다. 하나는 메시지 브로커이고 하나는 이벤트 브로커이다. 메시지 브로커의 가장 대표적인 제품은 RabbitMQ이고 이벤트 브로커의 가장 대표적인 제품은 Kafka 이다. 이 두가지를 비교해보며 어떤 서비스를 내 프로젝트에 사용하면 좋을지 생각해보았다. 

    RabbitMQ

    RabbitMQ(이하 RMQ)의 MQ는 Message Queue 이다. 말그대로 메시지를 큐 형태로 보관한다. 이때문에 프로듀서가 발행한 메시지를 큐어 순서대로 큐 뒤에 넣고 컨슈머는 큐 앞에서부터 메시지를 받아간다. 이는 메시지를 순차적으로 처리한다는 장점은 있지만 다음과 같은 단점들도 생긴다.

    메시지 브로커는 메시지를 받아오고 컨슈머가 메시지를 받아가면 이를 순차적으로 제거하는 역할까지 해야한다. 컨슈머는 순서는 고려할 필요없이 단순히 메시지를 요구하면 브로커가 알아서 순차적으로 메시지를 전달하고 제거하는것이다. 이런 형식을 Smart Broker, Dumb Consumer 라고 한다.

    이런점 때문에 RMQ는 분산 클러스터링이 까다로운편이다. 데이터의 입력뿐아니라 데이터의 삭제에대해서도 순서에맞게 각 노드들이 동기화 해줘야하기때문이다. RMQ는 이러한 이유로 주로 하나 또는 비교적 적은 수로 운영된다.

    또, RMQ는 메시지를 주로 메모리에 저장한다. 이때문에 빠른 처리가 가능하지만 데이터의 유실 위험이 있다. 

     

    뭔가 단점만 말한것 같지만 장점들도있다. 우선 메시지를 라우팅하는 규칙이 굉장히 다양하다. 복잡한 라우팅이 필요한경우 사용될 수 있다. 또한 컨슈머가 메시지를 가져가고 메시지를 성공적으로 처리됐는지 여부를 브로커에 전달하고 큐에서 메시지를 삭제할 수 있어 신뢰성 있는 전달을 보장할 수 있다. 

    Kafka

    Kafka는 메시지를 로그 형태로 디스크에 보관한다. 따라서 유실 위험이 RMQ에 비해 덜하다. 이 메시지들은 배열처럼 각각의 요소에 오프셋들을 가진다. 컨슈머들을 각각 자신이 마지막으로 가져간 오프셋을 기억한 후 다음 오프셋을 요청하여 가져간다. 브로커는 메시지를 넣어두기만하면 컨슈머가 알아서 가져간다. 이런 형식을 Dumb Broker, Smart Consumer 라고 한다. 컨슈머의 구현이 RMQ와 비교해 조금 더 복잡할 수 있다. 

    이런 오프셋을 가지고 접근한다는건 여러 장점들을 가질 수 있다. Kafka에서는 메시지를 처리한다고 메시지가 삭제되지 않는다. 컨슈머는 필요하다면 여러번 같은 오프셋의 메시지를 가져갈수도 있고, 장애가 발생했다면 특정 오프셋부터 다시 읽어갈 수도 있다. 또한 대규모 클러스터링에 매우 적합하다. 각각의 노드들은 데이터만 제때 동기화 해주면 된다. 가져가는건 컨슈머가 오프셋을 기반으로 알아서 가져간다.

    이때문에 카프카는 대규모 처리량을 필요하거나 실시간 스트리밍, 데이터 파이프라인등에 적합하다.

    결론

    나는 내 메일 서버와의 연동을 RMQ를 이용해 하기로했다. 첫번째 이유는, 내 메일 서버는 대규모 처리 할 필요가 없는 서비스이다. 내 서비스에서 메일은 현재 회원가입시 인증코드 전송 정도이다. 간단하게 RMQ 단일 노드로 충분히 처리 가능하다.

    또한 메시지들에 대해서 굳이 디스크에 저장할 필요도 없을것같다. 메일이 굉장히 크리티컬해서 반드시 와야하는거라면 모르겠지만 서비스를 사용하면서 메일이 안올경우 어떻게 하는가? 보통 재전송을 바로 눌러 다시 요청한다. 이와같은 이유로 메일 서버는 RMQ로 연동해도 충분할것으로 보인다.

    출처

    https://youtu.be/0lyrd5FlETQ?si=pJ7fml_PqTp8B3zB

     

    '공부방' 카테고리의 다른 글

    Proxy 와 Reverse Proxy  (0) 2024.06.18
    JPA 1대다 fetch join 주의사항  (0) 2024.04.02
    ElasticSearch 정리  (0) 2023.12.25
    파이프라인 프로토콜  (1) 2023.11.22
    HTTPS 통신 과정  (0) 2023.11.15
Designed by Tistory.