이벤트 기반 분산 시스템을 향한 여정
이벤트 기반 분산 시스템을 향한 여정
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)
'정보공유' 카테고리의 다른 글
The 3 Secrets of Highly Successful Graduates (0) | 2018.11.20 |
---|---|
Blitzscaling: Book Trailer (0) | 2018.11.20 |
Multiplayer Game Sync Techniques through CAP theorem (0) | 2018.11.19 |
점진적인 레거시 웹 애플리케이션 개선 과정 (0) | 2018.11.19 |
Developing SEO audits that maximize growth #dmssconference (0) | 2018.11.19 |
SEO Project Management for Successful Processes #TheInbounder (0) | 2018.11.16 |
문석진, 프로젝트DH의 절차적 애니메이션 시스템 Ⅱ, NDC2018 (0) | 2018.11.16 |
심예람, <프로젝트DH> AI 내비게이션 시스템, NDC2018 (0) | 2018.11.16 |