brunch

You can make anything
by writing

C.S.Lewis

by 에디의 기술블로그 Nov 30. 2017

스프링 클라우드, MQ 도입 사례(4)

- 관련 연구 3-Spring Cloud Stream,RabbitMQ연동

스프링 클라우드(Spring Cloud), MQ(Message Queuing) 를 연동한 서비스 도입 사례를 공유합니다. 


도입 배경 및 아키텍처 결정

관련 연구 1 - 기본 개념  

관련 연구 2 - RabbitMQ 

관련 연구 3 - Spring Cloud Stream, RabbitMQ 연동(현재글)

도입 사례 1 - Spring Cloud Stream, RabbitMQ 실제 서비스 연동

도입 사례 2 - 예상했던, 예상하지 못했던 추가 작업

부록 A - RabbitMQ 연동하는 다양한 방법

부록 B - Spring Cloud Stream 버전 이슈

정리


사내 서비스 개선사항이기 때문에 공개하기 어려운 대외비는 내용에서 제외하였습니다. 서비스 아키텍처는 외부에 공유해도 되겠다는 판단으로 공유합니다. 개선사항 의견을 말씀해 주시면 감사드리겠습니다. 



이전 포스팅 참고부탁드립니다. 

https://brunch.co.kr/@springboot/2

https://brunch.co.kr/@springboot/3

https://brunch.co.kr/@springboot/6




4. 관련연구 3 - Spring Cloud Stream, RabbitMQ 연동

  이번 글에서는 Spring Cloud Stream 및 RabbitMQ 연동 방법에 대해서 사전 학습하려고 합니다. 사실, 이 글을 읽기 전에 마이크로서비스 아키텍처에 대해서 조금이라도 이해하고 있다면 많은 도움이 될것 같습니다. 이번 글에서는 아주 간략하게 정리만 할 예정이고, 추후에... 내년 상반기??에는 마이크로서비스 아키텍처, 스프링 클라우드, 도커 등 다양한 주제로 심화학습하여 글을 작성할려고 합니다. 


4.1 스프링 클라우드(Spring Cloud)

  스프링 클라우드는 분산 시스템(e.g. configuration management, service discovery, circuit breakers, intelligent routing, micro-proxy, control bus, one-time tokens, global locks, leadership election, distributed sessions, cluster state)의 공통 패턴을 빠르게 구축할 수 있는 스프링 프레임워크 기술입니다. Spring Cloud 에 포함된 메인 프로젝트는 아래와 같습니다. 스프링 클라우드에 포함된 메인 프로젝트는 아래와 같습니다. 

spring-cloud-aws

spring-cloud-bus

spring-cloud-cli

spring-cloud-commons

spring-cloud-contract

spring-cloud-config

spring-cloud-dataflow

spring-cloud-netflix

spring-cloud-security

spring-cloud-cloudfoundry

spring-cloud-consul

spring-cloud-sleuth

spring-cloud-stream

spring-cloud-zookeeper

spring-cloud-task


  스프링 클라우드의 내용이 너무 많기 때문에 이 글에서 모두 다루기는 힘들것 같습니다. 공식 가이드 홈페이지를 참고하시면 될것 같습니다. 

http://projects.spring.io/spring-cloud/


4.2 Spring Cloud Stream(스프링 클라우드 스트림)

  Spring Cloud Stream(스프링 클라우드 스트림) 은 메시지 기반 마이크로 서비스를 구현하기 위한 프레임 워크입니다. Spring Cloud Stream은 Spring Boot를 기반으로 DevOps 친화적인 마이크로 서비스 애플리케이션을 만들고 Spring Integration은 메시지 브로커와의 연결을 제공합니다. Spring Cloud Stream은 메시지 브로커의 독창적인 구성을 제공하여 여러 미들웨어 공급 업체에 pub/sub, 소비자 그룹 및 파티션 개념을 도입합니다. 이 독창적인 구성은 스트림 처리 응용 프로그램을 만드는 기초를 제공합니다. 응용 프로그램에 @EnableBinding 을 추가하면 메시지 브로커에 즉시 연결되며 메서드에 @StreamListener를 추가하면 스트림 처리를 위한 이벤트가 수신됩니다.

  Spring Cloud Stream을 통해서 MQ 연동을 매우 쉽게 구현할 수 있습니다. 하지만, 자바 라이브러리에서 MQ 를 연동하는 방법, 스프링에서 MQ 를 연동하는 방법에 대해서는 미리 알 필요는 있습니다. 왜냐면, Spring Cloud Stream 의 백단에서 어차피 기존의 MQ 연동 메소드를 그대로 사용하기 때문입니다. Spring Cloud Stream은 어노테이션을 제공하여 쉽게 연동할 수 있도록 도와줄 뿐입니다. 물론, 백단 로직을 모른다해도 서비스 구현하는데는 전혀 문제가 되지는 않습니다. 그래도 알아두면 도움이 될것으로 판단됩니다. 자바 라이브러리에서 MQ 연동, 스프링에서 연동, Spring Cloud Stream 에서의 연동이 어떤 연관이 있는지에 대해서는 [부록 A - RabbitMQ 연동하는 다양한 방법]에서 상세하게 다룰 예정입니다. 

  그럼 다시 Spring Cloud Stream 에 대해서 다시 알아보겠습니다. Spring Cloud Stream 에서 Pub&Sub 개념의 Pub 역할을 하는 부분이 Source이고, Sub 의 역할이 Sink 입니다. 간략하게 그림으로는 아래와 같이 표현할 수 있습니다. 

Spring Cloud Stream Source, Sink [참고 - 구글 이미지]

 

 샘플소스는 아래 github 에서 참고하였습니다. 

https://github.com/spring-cloud/spring-cloud-stream-samples/blob/master/stream-listener/src/main/java/demo/SampleSink.java



SampleSink.java


@EnableBinding(SampleSink.Sink.class)
public class SampleSink {
            

            // Sink application definition

            @StreamListener(Sink.SAMPLE)
            public void receive(Foo fooMessage) {
                    System.out.println("At the Sink");

            }
            public interface Sink {
                    String SAMPLE = "sample-sink";


                    @Input(SAMPLE)
                     SubscribableChannel sampleSink();
            }      
}                        



속성 및 RabbitMQ 연결 정보는 아래와 같이 구현하면 됩니다. 


application-dev.properties

spring.cloud.stream.bindings.sample-sink.destination=abc

spring.rabbitmq.host=127.0.0.1

spring.rabbitmq.port=5672

spring.rabbitmq.username=guest

spring.rabbitmq.password=guest


아래와 같이 yml 파일로도 가능합니다. (참고로 github 의 샘플 소스는 아래와 같이 되어있습니다.)


application.yml

server:

  port: 8082

spring:

  cloud:

    stream:

      bindings:

        sample-sink:

          destination: abc


  참고로 최종 연동 단계에서는 application.properties 에 있는 RabbitMQ 연결 정보는 서버의 물리적인 경로에 배포하여 관리하였습니다. 개발,QA,실서비스의 연결 정보가 다 다르기 때문입니다. 해당 방법에 대해서는 다음 글(도입사례)에 자세히 작성하겠습니다. 그리고, 리스닝 이벤트가 발생하면 recive  를 실행하는 소스입니다만, 매개변수로 Foo 형식으로 받도록 구현되어있습니다. 샘플소스에는 아래와 같이 Foo.java 파일에 Foo 라는 클래스가 선언이 되어있습니다. 만약 전송 된 데이터가 Foo 와 매핑이 되지 않는다면 해당 listen 이벤트가 receive 내부 로직을 수행하지 않습니다. 


Foo.java


public class Foo {

        private String value;

        public String getValue() {

                return value;

        }

        public void setValue(String value) {

                this.value = value;

        }

}


    어쨋든 메시지를 정상적으로 수신했다면 System.out.println("At the Sink"); 가 실행이 될 것입니다. 메시지 수신만 소개를 했습니다만, 메시지 발행도 샘플 소스를 참고하시면 어렵지 않게 구현 하실수 있습니다. 메시지 발생 을 구축하지 않아도 RabbitMQ 관리툴에서 직접 메시지를 발행(전송)할 수 있습니다. 참고로 해당 샘플로 구현을 하면 Queue 이름은 익명으로 생성될 것입니다. 또한, Exchange Type 은 Topic 으로 셋팅될 것입니다. Binding Key 역시 Spring Cloud Stream 라이브러리 내부 로직에 의해서 정해질 것입니다. 물론 Exchange Type 과 Binding Key, Queue 이름 모두  properties 에서 설정할 수 있습니다! 단, Spring Cloud Stream 1.2.0 이상 버전부터 가능합니다. (1.1.3 버전에서는 Exchange Type 은 무조건 Topic 로 설정이 되고, Binding Key 역시 따로 설정할 수 없습니다. 아마도 초기에 구현한 Spring Cloud 프로젝트가 미흡한 점이 많았던것 같습니다, 물론 그 이후에 많이 보완이 되었습니다만...) 일단 저는 1.2.0 버전을 기준으로 글을 작성할 예정이기 때문에 properties 에 Exchange Type 과 Binding Key, Queue 이름 설정할 예정이며 실제 연동 사례는 다음 글 [도입 사례 1 - Spring Cloud Stream, RabbitMQ 실제 서비스 연동] 에서 작성할 예정입니다. 그리고 위에 설명한 Spring Cloud Stream 버전에 따른 이슈는 [부록 B - Spring Cloud Stream 버전 이슈] 에서 공유할 예정입니다. 혹시라도 궁금하시면 회사 개발팀 블로그에서 미리 확인하실 수 있습니다.

(글..작성이 깔끔하지는 않습니다; )

https://zumdev.github.io/spring_cloud_stream_rabbitmq_02/




  이번 [관련 연구 3 - Spring Cloud, Spring Cloud Stream] 에서는 Spring Cloud Stream 에 대해서 아주 간략하게 글을 작성해봤습니다. 지금까지 4번의 포스팅을 통해서 대략적인 배경, 관련연구를 정리해봤습니다. 이제 드디어... 다음 글에서는 [Spring Cloud Stream, RabbitMQ 실제 서비스 연동] 라는 주제로 실제로 서비스 연동 사례를 공유하겠습니다.

https://brunch.co.kr/@springboot/17


브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari