본문 바로가기
정보공유

이벤트 기반 분산 시스템을 향한 여정

by 날고싶은커피향 2018. 11. 19.
반응형

이벤트 기반 분산 시스템을 향한 여정





이벤트 기반 분산 시스템을 향한 여정

1. ORDER SYSTEMUSER SERVICE API GW PRODUCT SYSTEM SCM SYSTEM EXTERNAL SYSTEMS 
 MDM SYSTEMBACK-OFFICE SCM SYSTEM
 


2. SERVICE SERVICE SERVICE SERVICE SYSTEM  

3. ✔ ✔ (customizing) ✔ , 5 ✔ (Amazon Web Service)

4. LOGISTICS SYSTEM

5. LOGISTICS SYSTEM LOGISTICS ADAPTER ✔ Spring Boot (Java 1.8) ✔ AWS Elastic Beanstalk : https://allegro.tech/2015/01/working-with-legacy-architecture.html

6. LOGISTICS SYSTEM LOGISTICS ADAPTER

7. LOGISTICS SYSTEM LOGISTICS ADAPTER

8. LOGISTICS SYSTEM LOGISTICS ADAPTER • 기능 변경 또는 추가 시 많은 비용이 필요 • 코드 변경시 다양한 부수효과(side effect) 발생

9. LOGISTICS SYSTEM LOGISTICS ADAPTER

10. LOGISTICS SYSTEM LOGISTICS ADAPTER

11. . !"" build.gradle #"" src !"" config !"" main $   !"" java $   $   #"" com $   $      #"" woowahan $   $      #"" scm $   $      !"" purchase $   $         !"" domain $   $         !"" application $   $         #"" infrastructure $   $      !"" delivery $   $      #"" adapter $   $         !"" order $   $         !"" masterdata $   $         #"" logistics $   #"" resources #"" test

12. LOGISTICS SYSTEM LOGISTICS ADAPTER ✔ 부족한 비즈니스 지식과 도메인 이해도를 가지고 바로 시작할 수 있다. ✔ 필요하다면 빠르게 고칠 수 있고, 모델을 성장 시킬 수 있다. ✔ 잘 구성된 모듈은 단일 JVM에서 동작하는 마이크로서비스로 볼 수도 있다.

13. ✔ ✔ ✔ IDE LOGISTICS ADAPTER DeliveryService ----------------------
 +createInvoice(Order) PurchaseService ----------------------
 +createOrder(Order) WarehousingManagement -------------------------
 +process(OrderComplated) void process(OrderCompleted orderCompleted) { PurchaseOrder order = purchaseService.createOrder(..); logisticsOperations.register(order); DeliveryInvoice invoice = deliveryService.createInvoice(..); logisticsOperations.register(invoice); }

14. ✔ ✔ ✔ IDE @Transactional LOGISTICS ADAPTER DeliveryService ----------------------
 +createInvoice(Order) PurchaseService ----------------------
 +createOrder(Order) WarehousingManagement -------------------------
 +process(OrderComplated)

15. ✔ ✔ ✔ IDE LOGISTICS ADAPTER DeliveryService ----------------------
 +createInvoice(Order) PurchaseService ----------------------
 +createOrder(Order) WarehousingManagement -------------------------
 +process(OrderComplated)

16. LOGISTICS ADAPTER ✔ 새로운 기능을 추가하기 위해 기존 코드를 수정해야 함 ✔ 모듈간 상호 참조 등으로 순환 의존성이 생기는 등에 부작용 ✔ 즉, 모듈간 강결합으로 단일 모듈에 경계가 무너지는 현상 DeliveryService ----------------------
 +createInvoice(Order) PurchaseService ----------------------
 +createOrder(Order) WarehousingManagement -------------------------
 +process(OrderComplated) InventoryService ----------------------
 +adjustStock(Order)

17. DeliveryService PurchaseService InventoryService Warehousing Management

18. DeliveryService PurchaseService InventoryService Warehousing Management interface ApplicationEventPublisher { void publishEvent(ApplicationEvent event); void publishEvent(Object event); } class ApplicationComponent { @EventListener void handle(OrderCompleted orderCompleted) { } } interface ApplicationListener<E extends ApplicationEvent> extends EventListener { void onApplicationEvent(E event); }

19. DeliveryService PurchaseService class InventoryService { @EventListener void handle(OrderCompleted orderCompleted) { } } class OrderEventRelayer { @SqsListener("order-message-queue") void relayEvent(OrderCompletedMessage message) { applicationEventPublisher.publishEvent( message.toOrderCompleted() ); } }

20. LOGISTICS SYSTEM LOGISTICS ADAPTER

21. RPC Stub RPC Server SHARED LIBRARY

22. HTTP Client HTTP Server - (RESOURCE) - URI - (Verb) - HTTP Method - (Representations)

23. Messaging API Messaging API MESSAGING SYSTEM

24. PRODUCT SYSTEM ORDER SYSTEM REMOTE SYSTEMS RESTFUL API
 SERVICE ORDER ADAPTER EXTERNAL ADAPTERS MESSAGING SYSTEM LOGISTICS SERVICE DELIVERY SERVICE PURCHASE SERVICE

25. PRODUCT SYSTEM ORDER SYSTEM REMOTE SYSTEMS RESTFUL API
 SERVICE ORDER ADAPTER EXTERNAL ADAPTERS MESSAGING SYSTEM LOGISTICS SERVICE DELIVERY SERVICE PURCHASE SERVICE

26. RESTFUL API
 SERVICE ORDER ADAPTER EXTERNAL ADAPTERS MESSAGING SYSTEM LOGISTICS SERVICE DELIVERY SERVICE PURCHASE SERVICE 1) 최소한의 운영 비용으로 사용 할 수 있는가? 2) 메시지 전달 신뢰성을 가지고 있는가? 3) 단일 메시지가 여러 소비자에게 전달될 수 있는가? 4) 수평 확장성을 가지고 있는가? 5) 사용하기 쉬운가? 6) 모니터링 할 수 있는가?

27. ✔ 최소 1회 이상 메시지 전달 보장, 최대 14일 유지 ✔ 무제한 확장 가능, 빠른 읽기 처리량 ✔ 메시지 풀링 방식, 단일 소비자(경쟁 소비자) ✔ 메시지 순서를 보장하지 않음 ✔ 최대 256KB 데이터 전달 ✔ AWS SDK 기반 쉬운 API 제공 1) 최소한의 운영 비용으로 사용 할 수 있는가? 2) 메시지 전달 신뢰성을 가지고 있는가? 3) 단일 메시지가 여러 소비자에게 전달될 수 있는가? 4) 수평 확장성을 가지고 있는가? 5) 사용하기 쉬운가? 6) 모니터링 할 수 있는가?

28. 1) 최소한의 운영 비용으로 사용 할 수 있는가? 2) 메시지 전달 신뢰성을 가지고 있는가? 3) 단일 메시지가 여러 소비자에게 전달될 수 있는가? 4) 수평 확장성을 가지고 있는가? 5) 사용하기 쉬운가? 6) 모니터링 할 수 있는가? ✔ 발행/구독 모델 지원(1:1, 1:n) ✔ 무제한 확장 가능 ✔ 소비자 유형별 메시지 전달 보장 ✔ 메시지 전달 보장을 위해 SQS 사용 권장 ✔ 그외 소비자 유형에 대해서는 보장 못함 ✔ AWS SDK 기반 쉬운 API 제공

29. 1) 최소한의 운영 비용으로 사용 할 수 있는가? 2) 메시지 전달 신뢰성을 가지고 있는가? 3) 단일 메시지가 여러 소비자에게 전달될 수 있는가? 4) 수평 확장성을 가지고 있는가? 5) 사용하기 쉬운가? 6) 모니터링 할 수 있는가? ✔ 메시지 전달 및 순서를 보장 ✔ 이벤트 스트리밍 지원(중복 이벤트 제어 필요) ✔ 샤드(Shard) 개념을 통해 무제한 확장 가능 ✔ 자동화된 확장이 아닌, 수동 제어 ✔ 3개 리전에 복제, 최대 7시간 동안 데이터 유지 ✔ 초당 5회 읽기 제한(샤드 당) ✔ 최대 1MB 데이터 전달

30. 1) 최소한의 운영 비용으로 사용 할 수 있는가? 2) 메시지 전달 신뢰성을 가지고 있는가? 3) 단일 메시지가 여러 소비자에게 전달될 수 있는가? 4) 수평 확장성을 가지고 있는가? 5) 사용하기 쉬운가? 6) 모니터링 할 수 있는가? ✔ 메시지 전달 및 순서를 보장 ✔ 점대점, 발행/구독 방식 메시지 기능 지원 ✔ 인스턴스 기반 확장 가능 ✔ 높은 가용성 및 메시지 안정성 ✔ 업계 표준 API 및 프로토콜 호환 ✔ AMQP, MQTT, OpenWire, STOMP 지원 ✔ JMS(Java Message Service) 지원

31. PUBLISHER SUBSCRIBER
 #1 SNS TOPIC SQS #1 SQS #2 SQS #3 SUBSCRIBER
 #2 SUBSCRIBER
 #3

32. SENDER RECEIVERSQS RECEIVER

33. PUBLISHER AWS LAMBDA SNS HTTP ENDPOINT SQS

34. PRODUCT SYSTEM ORDER SYSTEM REMOTE SYSTEMS RESTFUL API
 SERVICE ORDER ADAPTER EXTERNAL ADAPTERS SNS LOGISTICS SERVICE DELIVERY SERVICE PURCHASE SERVICE SQS SQS

35. ORDER ADAPTER EXTERNAL ADAPTERS SCM
 SNS SERVICE SERVICE SERVICE SERVICE ORDER
 SERVICE ORDER
 SNS SERVICE SQS SQS ORDER SYSTEM SCM SYSTEM SQS

36. ORDER
 SYSTEM SCM SYSTEM class OrderCompletedEvent { private Order source; private Date occurredOn; public Order getSource() { .. } public void setSource(Order source) { .. } // getter, setter } { "source" : { "id" : "2018042129392759283",
 "buyer": {},
 "deliveryAddress": {}, "orderLines" : [] }, "occurredOn" : 1520393282506 }

37. - Message - MessageChannel
 - MessageConverter - MessageHandler

38. @SqsListener("scm-adapter-order-event-queue") void handle(OrderCompletedEvent event) { // } MessageSendingOperations operations = new NotificationMessagingTemplate(amazonSNS); operations.convertAndSend("order-event-stream", OrderCompletedEvent.of(order); ORDER
 SYSTEM SCM SYSTEM

39. @StreamListener(target = Sink.INPUT, condition = "payload.eventType == 'OrderCompletedEvent'") public void handle(@Payload OrderCompletedEvent event) { // handle event } @StreamListener(target=Sink.INPUT, condition="payload.eventType == 'OrderCanceledEvent'") public void handle(@Payload OrderCanceledEvent event) { // handle event } ORDER
 SYSTEM SCM SYSTEM

40. ORDER
 SYSTEM SCM SYSTEM eventMessagePublisher.publishEvent(domainEvent); @EventListener void handle(DomainEvent event) { }

41. /

42. /

43. / {

44. Spring Messaging Woowahan Messaging AWS Woowahan Messaging Spring Cloud AWS

45. interface DomainEventPublisher { void publishEvent(DomainEvent event); } interface DomainEventSubscriber { void onEvent(DomainEvent event); }

46. interface DomainEventPublisher { void publishEvent(DomainEvent event); } class AmazonSNSDomainEventPublisher implements DomainEventPublisher { private final NotificationMessagingTemplate messagingTemplate; private final String destinationName; @Override public void publishEvent(DomainEvent event) { Map<String, Object> headers = new HashMap<>(); { headers.put(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON_VALUE); } EventEnvelope<DomainEvent> payload = new EventEnvelope<>(event); messagingTemplate.convertAndSend(destinationName, payload, headers); } }

47. interface DomainEventSubscriber { void onEvent(DomainEvent event); } class AmazonSQSDomainEventSubscriber implements DomainEventSubscriber { private ApplicationEventPublisher applicationEventPublisher; private ObjectMapper objectMapper; @SqsListener("scm-adapter-order-event-queue") public void receive(@NotificationMessage JsonNode payload) { EventEnvelope eventEnvelope = objectMapper.treeToValue(payload, EventEnvelope.class); if (DomainEvent.class.isAssignableFrom(eventEnvelope.getEvent().getClass())) { onEvent((DomainEvent) eventEnvelope.getEvent()); } } @Override public void onEvent(DomainEvent event) { applicationEventPublisher.publishEvent(event); } } @EventListener void handle(OrderCompletedEvent event) { }

48. class OrderCompletedEvent { private Order source; private Date occurredOn; public Order getSource() { .. } public void setSource(Order source) { .. } // getter, setter } { "source" : { "id" : "2018042129392759283", "orderLines" : [] }, "occurredOn" : 1520393282506 } class OrderCompletedEvent { private Order source; private Date occurredOn; public Order getSource() { .. } public void setSource(Order source) { .. } // getter, setter }

49. { "event" : { "@eventType" : "woowabros.order.domain.event.OrderCompletedEvent", "source" : { "id" : "2018042129392759283", "orderLines" : [] }, "occurredOn" : 1520393282506 } } ObjectMapper objectMapper = new ObjectMapper(); objectMapper.enableDefaultTyping(); OrderCompletedEvent event = OrderCompletedEvent.of(Order.createTemporaryOrder()); EventEnvelope envelope = EventEnvelope.wrap(event); String orderCompletedEventJSON = objectMapper.writeValueAsString(envelope); JavaType javaType = objectMapper.constructType(EventEnvelope.class); EventEnvelope envelope = objectMapper.readValue(orderCompletedEventJSON, javaType); OrderCompletedEvent event = (OrderCompletedEvent) envelope.getEvent();

50. ✔ ✔ ✔ , (EIP ) ✔ CQRS ✔ , ✔ ✔ ✔ Event Sourcing, etc ✔ ✔ ✔ (SQS) ✔ Amazon Kinesis

51. EXTERNAL SYSTEMS PRODUCT SYSTEM ORDER SYSTEM EVENT STREAM

52. ORDER SYSTEMUSER SERVICE API GW PRODUCT SYSTEM SCM SYSTEM EXTERNAL SYSTEMS 
 MDM SYSTEMBACK-OFFICE SCM SYSTEM

53. ORDER SYSTEMUSER SERVICE API GW PRODUCT SYSTEM SCM SYSTEM EXTERNAL SYSTEMS 
 MDM SYSTEMBACK-OFFICE SCM SYSTEM

54. ✔ , (Implementing Domain-Driven Design) ✔ , (Domain-Driven Design Distilled) ✔ , 5.0 2/e(Spring 5.0 Microservices - Second Edition)

반응형

loading