우아한 형제들 세미나 : 이벤트 기반 분산 시스템을 향한 여정

우아한형제들:이벤트 기반 분산 시스템을 향한 여정 내용 정리

모놀리식 시스템

  • 단일 시스템(BO,PO,EAPI) 안에서 모듈들 (ItemService, DeliveryService, InventoryService) 이 직접 참조한 구조
  • 직접적으로 참조하기 때문에 너무 강하게 결합되어있음
  • 이벤트 Driven을 통해서 모듈간의 관계를 느슨하게 할 수 있다고 생각함

이벤트 생산과 서비스를 통한 느슨한 결합

  • Event Publisher, Evnet Channel, Event Consumer 로 분리할 수 있음
  • 스프링에서는 이러한 이벤트 메커니즘을 애플리케이션 레벨로 개발할 수 있음
  • Event Producer (Warehousing Management - bo,po,eapi)
    interface ApplicationEventPublisher {
      void publishEvent(ApplicationEvent event);
      void publishEvent(Object event);
    }
    
  • Event Consumer
    // 1. 첫번째 방법
    interface ApplicationListner<E extends ApplicationEvent> extends EventListner {
      void onApplicationEvent(E evnet);
    }
    
    // 2. 두번째 방법 (스프링 4.2 부터는 어노테이션을 통해 구현할 수 있음)
    class ApplicationComponent {
      @EventListner
      void handle(OrderCompleted OrderCompleted) { }
    }
    
  • Event Channel은 ApplicationContext이 그 역할을 해준다.

시스템 또는 서비스 통합을 위한 세가지 방법

  • 원격 프로시져 호출 (Remote Procedure Call)
    • Shared Library 를 Client 와 Java Service 사이에 두고 서로 공유 -> 강한 결합성이 생김
    • 구글의 GRCP는 강력한 성능을 발휘함
  • 레스트풀 API (RESTful API)
    • HTTP 프로토콜 기반
    • 장애, 트랜잭션 등을 어떻게 관리할지 고민을 해야함
  • 메시징
    • 비동기 메시지 전달 -> 시스템간 결합성 느슨함

요청과 응답은 동기방식에 가깝고 이벤트기반은 비동기로 생각할 수 있음

  • 동기방식이 필요한 부분에 대해선 RestfulAPI를 사용하고 비동기방식이 필요한 부분에는 메시징을 사용하기로 함
  • 데이터를 실시간으로 끌어가는 부분에 대해선 RestfulAPI가 동작을 하게 될것이고 어떤 작업을 해야해! 라고 하는 부분에 대해선 메시징을 쓰자
  • 어뎁터 서비스를 이용해서 메시지를 통제!

메시징 시스템은 어떤 것을 사용할 것인가?

  • 최소한의 운영 비용으로 사용할 수 있는가?
  • 메시지 전달 신뢰성을 가지고 있는가?
  • 단일 메시지가 여러 소비자에게 전달될 수 있는가?
  • 수평 확장성을 가지고 있는가?
  • 사용하기 쉬운가?
  • 모니터링 할 수 있는가?

배민찬에서는 AWS 메시징 솔루션 특징을 위 항목을 기준으로 검토

  • Amazon SNS/SQS 를 조합해서 사용하기로 함
  • SNS 에 이벤트가 모아지고, SQS 를 통해 전파하는 방식
  • Service - Adapter - SCM/SNS
    • 서비스에서 이벤트가 발행이되면, 어댑터가 중요한 이벤트만 뽑아서 발행하는 일종의 필터 역할을 하도록 아키텍쳐를 설계함

메시지는 도메인 이벤트를 싣고..

  • Message(DomainEvent) POJO 형식의 이벤트로 전파
  • POJO로 작성한 도메인 이벤트
    class OrderCompleteEvent {
        private Order source;
        private Order occurenceOn;
    
        public Order getSource() {...}
        public void setSource(Order source) {...}
    }
    
  • JSON 으로 표현한 이벤트 메시지
      {
        "source" : {
          "id" : "20210717235959000000",
          "buyer" : {},
          "deliveryAddress" : {},
          "orderLines" : []
        },
        "occurenceOn" : 1520393282506
      }
    

Order System <-> SCM System 으로의 Message 를 발행하고 구독하는데 어떤 시스템을 쓸까?

스프링 메시징 모듈, 메시징 통합지원 (Spring Messaging - 스프링 4.0부터 지원)

  • Message
  • MessageChannel
  • MessageConverter
  • MessageHandler 로 구성되어 있음. 이를 구현한 구현체는 여러가지가 있는데
  • Spring JMS
  • Spring AMQP
  • Spring Kafka
  • Spring Cloud AWS
  • Spring Cloud Stream

배민찬에서는 AWS를 사용하기 때문에, Spring Cloud AWS 를 사용하기로 함

  • @SqsListner("scm-adapter-order-event-queue") 를 통해서 해당 큐에 이벤트를 받을 수가 있음. 하지만 단점이, 저 큐에는 하나의 타입의 이벤트만 받을 수 있게 되어 있다
  • Spring Cloud Stream 으로 이벤트 타입을 구분지어서 다중 바인드를 할 수 있다. (하지만 SNS/SQN은 지원안함)

위의 기술을 이용해서 Spring Cloud AWS 를 이용한 Woowahan AWS Messaging -> Woowahan Messaging -> Spring Messaging “메시징 어뎁터” 신설

태그:

업데이트:

댓글남기기