[java] Spring Cloud Stream을 이용한 이벤트 기반 마이크로서비스 구현

이벤트 기반 아키텍처는 마이크로서비스 아키텍처에서 많이 사용되는 패턴 중 하나입니다. 이 패턴은 서비스간의 결합도를 낮추고 독립적으로 개발 및 배포할 수 있도록 해주는 장점이 있습니다. 이번 글에서는 이벤트 기반 아키텍처를 구현하기 위해 Spring Cloud Stream 프레임워크를 사용하는 방법에 대해 알아보겠습니다.

Spring Cloud Stream 소개

Spring Cloud Stream은 스프링 프레임워크 기반의 마이크로서비스 아키텍처에서 이벤트 기반 통신을 쉽게 구현할 수 있도록 도와주는 프레임워크입니다. Spring Cloud Stream은 메시지 브로커를 통해 이벤트를 전송하고 수신하는 추상화 계층을 제공합니다. 메시지 브로커는 RabbitMQ, Apache Kafka, Apache ActiveMQ 등 다양한 브로커를 지원합니다.

프로젝트 설정

Spring Cloud Stream을 사용하기 위해서는 먼저 프로젝트 설정이 필요합니다. 프로젝트의 pom.xml 파일에서 Spring Cloud Stream의 의존성을 추가해주어야 합니다. 아래는 Maven을 사용하는 경우의 예시입니다.

<dependencies>
  ...
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-stream</artifactId>
    <version>3.0.4</version>
  </dependency>
  ...
</dependencies>

또한, application.properties 파일에서 Spring Cloud Stream의 설정을 정의해주어야 합니다. 아래는 RabbitMQ를 사용하는 경우의 예시입니다.

spring.cloud.stream.bindings.input.destination=myInputTopic
spring.cloud.stream.bindings.output.destination=myOutputTopic
spring.cloud.stream.rabbit.bindings.input.consumer.bindingRoutingKey=myInputTopic
spring.cloud.stream.rabbit.bindings.output.producer.bindingRoutingKey=myOutputTopic
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

이벤트 수신자 구현

이제 이벤트 수신자를 구현해보겠습니다. 이벤트 수신자는 @EnableBinding 어노테이션을 사용하여 Spring Cloud Stream에 바인딩되도록 설정합니다.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.messaging.handler.annotation.Payload;

@SpringBootApplication
@EnableBinding(MyBinding.class)
public class EventReceiverApplication {

    public static void main(String[] args) {
        SpringApplication.run(EventReceiverApplication.class, args);
    }

    @StreamListener(target = MyBinding.INPUT)
    public void receiveEvent(@Payload Event event) {
        // 이벤트 수신 처리 로직 작성
    }
}

위의 코드에서 MyBinding.INPUT은 입력 이벤트를 수신하는 것을 의미합니다. @StreamListener 어노테이션을 사용하여 이벤트 수신 로직을 작성할 수 있습니다.

이벤트 발행자 구현

이번에는 이벤트 발행자를 구현해보겠습니다. 이벤트 발행자는 @EnableBinding 어노테이션을 사용하여 Spring Cloud Stream에 바인딩되도록 설정합니다.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.messaging.support.MessageBuilder;

@SpringBootApplication
@EnableBinding(Source.class)
public class EventPublisherApplication {

    private final Source source;

    public EventPublisherApplication(Source source) {
        this.source = source;
    }

    public static void main(String[] args) {
        SpringApplication.run(EventPublisherApplication.class, args);
    }

    public void publishEvent(Event event) {
        source.output().send(MessageBuilder.withPayload(event).build());
    }
}

위의 코드에서 Source 인터페이스는 출력 이벤트를 발행하는 것을 의미합니다. MessageBuilder를 사용하여 이벤트를 생성한 후 source.output().send() 메소드를 통해 이벤트를 발행할 수 있습니다.

결론

Spring Cloud Stream을 사용하면 이벤트 기반 아키텍처를 쉽게 구현할 수 있습니다. 이벤트 수신자와 이벤트 발행자를 구현하는 것은 매우 간단하며, 메시지 브로커를 통해 이벤트를 전송 및 수신할 수 있습니다. Spring Cloud Stream은 다양한 메시지 브로커를 지원하므로 프로젝트의 요구사항에 맞게 선택하여 사용할 수 있습니다.

더 많은 내용은 Spring Cloud Stream 문서를 참고하시기 바랍니다.