
https://mozzi-devlog.tistory.com/34
https://velog.io/@holicme7/Apache-Kafka-카프카란-무엇인가
https://velog.io/@choidongkuen/서버-메세지-큐Message-Queue-을-알아보자#-메세지-지향-미들웨어mom
이번에 우리 서비스에 FCM을 이용한 푸시 알림을 구현하게 되었다.
원래 우리 백엔드는 하나의 API 서버로 운영되었고, 댓글 생성과 같은 특정 API의 마지막에 푸시 알림을 전송하는 코드를 넣어주려고 하였다.
그러나 같은 백엔드 팀원분께서 아예 알림 서버를 분리하고, Kafka를 이용해 처리하자고 제안을 해주셨다.
물론 서비스 규모가 작아 과하게 느껴질 수 있지만, 학습 목적이 컸기 때문에 적용해 보고자 한다.
그래서 우선 MSA와 메시지 큐 시스템에 대해 알아보고자 한다.
모놀리식 아키텍처(MA)는 전통적인 개발 방식으로 하나의 프로젝트에 모든 기능을 함께 포함하는 구조
코드 베이스가 커질 수록 개발 및 배포에 복잡성이 증가

초기 개발에 유리하며 빠르게 프로토타입을 개발할 수 있음
필요한 모든 기능을 한 번만 호출하기 때문에 복잡한 통신 없이 직접 사용할 수 있음
그러나 코드 베이스가 커질 수록 복잡해지고 유지보수 및 확장이 어려움
일부 기능을 수정하거나 업데이트를 하려면 전체 애플리케이션을 재배포 해야함
간단한 소규모 프로젝트나 프로토타입 제작 및 단기 프로젝트에 적합
마이크로 서비스 아키텍처(MSA)는 작고 독립적인 서비스들의 집합으로 구성된 애플리케이션 구조
전체 시스템이 분산되어 있어 개발, 배포를 독립적으로 진행할 수 있으며 확장성과 유지관리가 용이

서비스 간 독립성으로 인해 확장성과 유연성이 높아짐
기능 고립성이라는 특징 때문에 일부 서비스가 실패하더라도 전체 시스템에 큰 영향을 미치지 않음
그러나 서비스간 통신이 필요하며, 서로 간 연결 구축 및 관리의 복잡성이 증가함
초기 개발 및 통신 등에 시간이 소요됨
대규모 및 복잡한 프로젝트나 독립적인 시스템을 개발하고 확장해야 하는 경우에 적합
우선 메세지 지향 미들웨어란 응용 소프트웨어 간의 비동기적 데이터 통신을 위한 소프트웨어
즉, 비동기적(Asynchronous) 한 방식을 이용해서 프로세스간의 데이터를 주고 받는 기능을 위한 시스템
메시지 지향 미들웨어는 아래와 같은 장점이 있음
메시지 큐는 이러한 메시지 지향 미들웨어에 속함
일단 큐(Queue)란 선입선출의 자료구조
메세지 큐(Message Queue)란 Queue 자료구조를 채택해서 메세지를 전달하는 시스템으로, 메세지 지향 미들웨어(MOM) 을 구현한 시스템
메세지를 발행하고 전달하는 부분을 Producer, 메세지를 받아서 소비하는 부분을 Consumer라고 부름
메세지 큐는 Producer 와 Consumer 의 메세지 전달 역할을 하는 매개체
MSA(Microservice Architecture)에서 어플리케이션 끼리의 상호작용에서 발생하는 데이터의 흐름을 담당하는 핵심적인 역할
메시지 큐에는 브로커라는 개념이 존재
메세지 큐가 메세지 혹은 이벤트가 송신되고 수신되는 하나의 통신 통로라고 하면 브로커는 메세지 큐에 메세지 혹은 이벤트를 넣어주고 중개하는 역할을 하는 주체
메시지 큐에서 데이터를 운반하는 방식에 따라 브로커는 메세지 브로커 와 이벤트 브로커 로 나눌 수 있음
메시지 큐는 아래와 같은 장점이 있음
만약 메시지 큐가 없다면 Producer 역할의 애플리케이션은 자신의 메시지를 전달 받는 Consumer 역할의 애플리케이션에게 직접적으로 메시지를 보냄
이 과정이 완료되기 전까지는 다른 메시지 전달 과정은 이루어지지 못하며, 이는 비효율적 → 동기 방식의 단점
만약 메시지 큐를 중간에 배치하면 Producer 애플리케이션은 Consumer 애플리케이션으로 바로 메시지를 보내는 것이 아닌 Queue에 메시지를 넣기만 하면 됨
이 메시지들을 Consumer가 비동기적으로 처리하는 것
메시지 큐를 중간에 둠으로써 하나의 서비스를 구성하는 애플리케이션끼리의 결합도를 낮출 수 있음
애플리케이션의 결합도를 낮추면 확장성, 유연성, 유지보수의 용이성 등 여러 장점이 있음
탄력성이란 시스템이 예기치 않은 상황 또는 장애에 대응하고 유연하게 대처할 수 있는 능력
특정 서비스 로직에 A → B의 프로세스가 있다고 할 때, 결합도가 높다면 B에서 발생한 장애가 A에도 영향을 미칠 확률이 높아 A 작업도 정상적으로 처리되지 않을 수 있음
그러나 메시지 큐를 활용하면 B 프로세스의 장애가 발생하더라도 A 프로세스의 작업에서 생기는 메시지들을 보관해 두었다가, 장애를 해결한 후 B 프로세스를 진행할 수 있음
과잉이란 정상적인 메시지 송/수신이 실패하는 경우 재실행이 가능하다는 뜻
메시지 큐가 없다면 위의 예시와 같이 A, B 프로세스는 End-to-End 통신을 하여 B의 장애 기간동안 시스템 응답성 저하, 데이터 불일치, 메시지 유실 등의 여러가지 문제점이 생길 수 있음
메시지 큐를 사용하면 작업을 메시지로 큐에 넣어두고, 장애 기간동안 쌓인 큐를 장애 복구 이후 정상적으로 재시도 및 처리할 수 있음
신뢰성이란 송신된 메시지의 안전하고 확실한 전달을 의미
위에서 설명한 장점들과 비슷하게 장애가 발생하더라도 Consumer는 송신되는 메시지를 안전하고 확실하게 수신할 수 있음
여기서 확장성은 수평 확장을 의미
기존 메시지 큐를 이용한 통신에서 부하가 증가하거나 클라이언트의 동시다발적인 요청이 증가할 때, 단순히 메시지 큐에 Producer와 Consumer를 추가함으로써 비교적 간단하고 쉽게 확장할 수 있음
메시지 지향 미들웨어(MOM)를 위한 개방형 표준 응용 계층 프로토콜 AMQP 사용
AMQP는 일반적인 메시지 큐와 비슷하지만 Exchange라는 라우터가 존재하며 Binding이라는 개념이 존재
아래는 RqbbitMQ의 구성요소
RabbitMQ는 AMQP 프로토콜을 구현해 놓은 오픈 소스 메시지 브로커
아래와 같은 특징이 있음
RabbitMQ의 처리 과정은 아래와 같음
RabbitMQ는 메시지 큐 내용을 메모리에 저장하여 재가동시 큐 내용이 손실될 수 있으며, Producer와 Consumer의 결합도가 높다는 단점이 있음
메시지 큐 및 Publish/Subscribe 패턴과 같은 메시지 기반 통신을 추상화하고 표준화한 JMS라는 API가 존재
Java MOM 표준 API로, 소프트웨어 응용 프로그램 구성 요소가 소비하는 요청, 보고서 또는 이벤트로 메시지를 작성, 전송, 수신 및 읽을 수 있는 메시징 표준
다른 시스템의 프로그램이나 다른 언어로 작성된 프로그램이 메시지를 통해 서로 조정할 수 있도록 함
ActiveMQ는 JMS 스펙을 좀 더 사용하기 편리하게 구현한 오픈소스 메시지 브로커
아래는 ActiveMQ의 구성요소
ActiveMQ의 처리 모델

그리고 이제 우리가 사용하기로 한 Kafka에 대해 조사해 보았음
카프카(Kafka)는 파이프라인, 스트리밍 분석, 데이터 통합 및 미션 크리티컬 애플리케이션을 위해 설계된 고성능 분산 이벤트 스트리밍 플랫폼
Pub-Sub 모델의 메시지 큐 형태로 동작하며 분산환경에 특화
RabbitMQ, ActiveMQ는 메시지 브로커지만 Kafka는 이벤트 브로커
링크드인(linked-in)에서 개발
아래는 카프카 개발 전 링크드인의 데이터 처리 시스템

위 구조는 아래와 같은 문제점이 있음
이러한 문제를 해결하기 위해 모든 시스템으로 데이터를 전송할 수 있고, 실시간 처리도 가능하며, 급속도로 성장하는 서비스를 위해 확장이 용이한 시스템을 만들고자 하였음 → 모든 이벤트/데이터의 흐름을 중앙에서 관리하는 카프카를 개발
아래는 카프카를 적용한 후 데이터 처리 시스템

대용량 실시간 로그처리에 특화되어 설계된 메시징 시스템으로 TPS가 매우 우수
메시지를 메모리에 저장하는 기존 메시징 시스템과는 달리 디스크에 저장 → 카프카를 재시작해도 메시지 유실 우려가 감소
일반적으로 하드디스크는 메모리보다 수백배 느리지만 하드디스크의 순차적 읽기에 대한 성능은 메모리보다 크게 떨어지지 않음 → 카프카는 파일 시스템을 활용한 고성능 디자인으로 성능을 보장
기본 메시징 시스템(rabbitMQ, ActiveMQ)에서는 브로커가 컨슈머에게 메시지를 push해 주는 방식인데, 카프카는 컨슈머가 브로커로부터 메시지를 직접 가져가는 PULL 방식으로 동작 → 컨슈머는 자신의 처리 능력만큼의 메시지만 가져와 최적의 성능을 낼 수 있음


위는 카프카의 내부 구조
카프카는 Pub-Sub 모델의 메세지 큐 형태로 동작
구성 요소는 아래와 같음
동작 원리는 아래와 같음
Kafka는 대규모 트래픽 처리 및 분산 처리에 효과적이며, 클러스터 구성, Fail-over, Replication 같은 기능이 있음
다른 메시지 큐 시스템들보다 빠른 100Kb/sec 정도의 속도를 가지고, 디스크에 메세지를 특정 보관 주기동안 저장하여 데이터의 영속성이 보장되고 유실 위험이 적음
또한 Consumer 장애 시 메시지를 보관해 두었다가 Consumer 복구 후 재처리가 가능
다음에는 Kafka를 Spring Boot에서 사용해 보도록 할 것!