consumer

Consumer

broker가 보낸 메시지를 ConsumerId로 식별된 핸들러에 라우팅하는 모듈입니다.

개요

사용자 애플리케이션이 broker로부터 메시지를 받아 등록된 핸들러로 라우팅할 때 사용하는 모듈입니다.

요구사항

consumer를 사용하려면 다음 환경이 필요합니다.

항목 최소 버전
Java 17
Spring Boot 3.2.0

설치

consumer는 JitPack으로 배포됩니다.
build.gradle에 의존성을 추가해 주세요.

build.gradle (Groovy DSL)

build.gradle
repositories {
    mavenCentral()
    maven { url "https://jitpack.io" }
}

dependencies {
    implementation "com.github.moko-meringue.mmmq:consumer:0.0.2"
}

build.gradle.kts (Kotlin DSL)

build.gradle.kts
repositories {
    mavenCentral()
    maven("https://jitpack.io")
}

dependencies {
    implementation("com.github.moko-meringue.mmmq:consumer:0.0.2")
}

Consumer

Consumer는 broker가 보낸 메시지를 수신해 등록된 핸들러를 호출하는 클래스입니다.
Spring 자동 구성으로 빈이 등록되므로 사용자가 직접 정의할 필요는 없습니다.

POST /mmmq/messages 엔드포인트

Consumer@PostMapping("/mmmq/messages")를 통해 broker가 보낸 메시지를 수신합니다.
수신 포트는 Spring Boot의 server.port 값을 그대로 사용합니다.

application.yml
server:
  port: 8081

라우팅

Consumer는 수신한 메시지를 동기로 다음 순서에 따라 처리합니다.

  1. 요청의 mmmq-consumer-id 헤더에서 ConsumerId를 읽습니다.
    헤더가 없거나 형식이 잘못된 경우 핸들러를 호출하지 않고 NACK를 반환합니다.
  2. ConsumerId로 등록된 핸들러를 찾습니다.
    매칭되는 핸들러가 없으면 NACK를 반환합니다.
  3. 요청을 받은 Tomcat 스레드 위에서 핸들러를 실행합니다.
  4. 핸들러가 예외 없이 끝나면 ACK, 예외가 던져지면 NACK를 같은 HTTP 응답으로 돌려줍니다.
주의
동기 처리 모델은 핸들러 실행이 끝날 때까지 broker의 워커가 대기한다는 의미입니다.
핸들러가 오래 걸리는 작업이라면 핸들러 내부에서 비동기로 위임하거나, broker 쪽 Dispatcher를 분리해 처리 경로를 나누는 것이 좋습니다.

응답

응답은 JSON입니다.

응답
{ "acknowledgement": "ACK" }
응답 의미
ACK 핸들러가 예외 없이 처리 완료했습니다.
NACK ConsumerId 헤더 누락 또는 형식 오류, 매칭 핸들러 부재, 핸들러 실행 중 예외 등의 사유로 처리에 실패했습니다.

MMMQListener

MMMQListener는 consumer에 핸들러를 등록하기 위한 API입니다.

참고
핸들러는 ConsumerId로 식별됩니다. 같은 ID를 가진 핸들러는 한 consumer 안에 하나만 존재할 수 있으며, 중복이 발견되면 시작 시점에 거부됩니다.
각 핸들러는 자신에게 라우팅된 메시지를 도착한 순서대로 받습니다.

어노테이션 방식

일반 Spring Bean 메서드에 @MMMQListener(id = "...")를 붙이면 자동으로 등록됩니다.
같은 클래스 안에 서로 다른 ID의 핸들러를 여러 개 둘 수 있습니다.

OrderService.java
@Service
public class OrderService {

    @MMMQListener(id = "order-created")
    public void handleOrderCreated(Order order) {
        // JSON 본문이 Order로 자동 역직렬화되어 전달됩니다.
    }

    @MMMQListener(id = "payment-completed")
    public void handlePaymentCompleted(Map<String, Object> payment) {
        // Map 형태로 받을 수도 있습니다.
    }
}

어노테이션 속성

속성 타입 설명
id String 핸들러를 식별하는 ConsumerId 값.

메서드 매개변수

메서드 매개변수 타입은 자유롭게 정할 수 있으며, broker가 보낸 메시지의 content가 Jackson으로 역직렬화되어 전달됩니다.

인터페이스 방식

제네릭 타입 정보를 컴파일 타임에 보존하고 싶을 때 사용합니다.
MMMQListener<T>를 구현한 Spring Bean이 자동으로 등록됩니다.

PaymentEventListener.java
@Service
public class PaymentEventListener implements MMMQListener<PaymentEvent> {

    @Override
    public String id() {
        return "payment-event";
    }

    @Override
    public void handle(PaymentEvent event) {
        // 런타임 제네릭 해석으로 PaymentEvent 그대로 받습니다.
    }
}

인터페이스 메서드

메서드 반환 / 매개변수 설명
id() String 핸들러를 식별하는 ConsumerId 값을 반환합니다.
handle(T) T 제네릭 타입 T로 역직렬화된 메시지 본문을 받아 처리합니다.