From 16903df8a72015dfa4dad252a3f8beff87381c58 Mon Sep 17 00:00:00 2001 From: Jinyoung Jang Date: Sun, 19 Apr 2020 15:12:15 +0900 Subject: [PATCH] Update README.md --- README.md | 125 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 91 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 44644e6..1713937 100644 --- a/README.md +++ b/README.md @@ -176,14 +176,102 @@ http localhost:8081/orders/1 ``` -### 폴리글랏 퍼시스턴스 / 플랫폼 +### 폴리글랏 퍼시스턴스 -고객관리 서비스의 시나리오인 주문상태, 배달상태 변경에 따라 고객에게 카톡메시지 보내는 기능의 구현 파트는 해당 팀이 python 을 이용하여 구현하기로 하였다. 해당 파이썬 구현체는 각 이벤트를 수신하여 처리하는 Kafka consumer 로 구현되었고 코드는 다음과 같다: +앱프런트 (app) 는 서비스 특성상 많은 사용자의 유입과 상품 정보의 다양한 콘텐츠를 저장해야 하는 특징으로 인해 RDB 보다는 Document DB / NoSQL 계열의 데이터베이스인 Mongo DB 를 사용하기로 하였다. 이를 위해 order 의 선언에는 @Entity 가 아닌 @Document 로 마킹되었으며, 별다른 작업없이 기존의 Entity Pattern 과 Repository Pattern 적용과 데이터베이스 제품의 설정 (application.yml) 만으로 MongoDB 에 부착시켰다 + +``` +# Order.java + + +# OrderRepository.java + + +# application.yml + + +``` + +MongoDB 를 이후 운영단계에서도 사용할 수 있게 하기 위해서 deployment.yaml 을 아래와 같이 설정하였다: ``` ``` +### 폴리글랏 프로그래밍 + +고객관리 서비스(customer)의 시나리오인 주문상태, 배달상태 변경에 따라 고객에게 카톡메시지 보내는 기능의 구현 파트는 해당 팀이 python 을 이용하여 구현하기로 하였다. 해당 파이썬 구현체는 각 이벤트를 수신하여 처리하는 Kafka consumer 로 구현되었고 코드는 다음과 같다: +``` +from flask import Flask +from redis import Redis, RedisError +from kafka import KafkaConsumer +import os +import socket + + +# To consume latest messages and auto-commit offsets +consumer = KafkaConsumer('fooddelivery', + group_id='', + bootstrap_servers=['localhost:9092']) +for message in consumer: + print ("%s:%d:%d: key=%s value=%s" % (message.topic, message.partition, + message.offset, message.key, + message.value)) + + # 카톡호출 API +``` + +파이선 애플리케이션을 컴파일하고 실행하기 위한 도커파일은 아래와 같다 (운영단계에서 할일인가? 아니다 여기 까지가 개발자가 할일이다. Immutable Image): +``` +FROM python:2.7-slim +WORKDIR /app +ADD . /app +RUN pip install --trusted-host pypi.python.org -r requirements.txt +ENV NAME World +EXPOSE 8090 +CMD ["python", "policy-handler.py"] +``` + + +### 동기식 호출 과 Fallback 처리 + +분석단계에서의 조건 중 하나로 주문(app)->결제(pay) 간의 호출은 동기식 일관성을 유지하는 트랜잭션으로 처리하기로 하였다. 호출 프로토콜은 이미 앞서 Rest Repository 에 의해 노출되어있는 REST 서비스를 FeignClient 를 이용하여 호출하도록 한다. + +- 결제서비스를 호출하기 위하여 Stub과 (FeignClient) 를 이용하여 Service 대행 인터페이스 (Proxy) 를 구현 + +``` +# (app) 결제이력Service.java + +package fooddelivery.external; + +@FeignClient(name="pay", url="http://localhost:8082")//, fallback = 결제이력ServiceFallback.class) +public interface 결제이력Service { + + @RequestMapping(method= RequestMethod.POST, path="/결제이력s") + public void 결제(@RequestBody 결제이력 pay); + +} +``` + +- 주문을 받은 직후(@PostPersist) 결제를 요청하도록 처리 +``` +# Order.java (Entity) + + @PostPersist + public void onPostPersist(){ + + fooddelivery.external.결제이력 pay = new fooddelivery.external.결제이력(); + pay.setOrderId(getOrderId()); + + Application.applicationContext.getBean(fooddelivery.external.결제이력Service.class) + .결제(pay); + } +``` + +- 서킷브레이커, 폴백의 은 운영단계에서 설명한다. + ### 비동기식 호출 / 시간적 디커플링 / 장애격리 / 최종 (Eventual) 일관성 테스트 + + ``` #상점 서비스를 잠시 내려놓음 kill (lsof -i ) @@ -234,38 +322,7 @@ http localhost:8080/주문s 품목=피자 수량=2 주소=서울 #성공 * 서킷 브레이킹 프레임워크의 선택: Spring FeignClient + Hystrix 옵션을 사용하여 구현함 -시나리오는 단말앱(app)-->결제(pay) 시의 연결을 RESTful Request/Response 로 연동하여 요청이 쇄도할 경우 CB 를 통하여 장애격리하는 시나리오. - -- 결제서비스를 호출하기 위하여 Stub과 (FeignClient) 를 이용하여 Service 대행 인터페이스 (Proxy) 를 구현 - -``` -# (app) 결제이력Service.java - -package fooddelivery.external; - -@FeignClient(name="pay", url="http://localhost:8082")//, fallback = 결제이력ServiceFallback.class) -public interface 결제이력Service { - - @RequestMapping(method= RequestMethod.POST, path="/결제이력s") - public void 결제(@RequestBody 결제이력 pay); - -} -``` - -- 주문을 받은 직후(@PostPersist) 결제를 요청하도록 처리 -``` -# Order.java (Entity) - - @PostPersist - public void onPostPersist(){ - - fooddelivery.external.결제이력 pay = new fooddelivery.external.결제이력(); - pay.setOrderId(getOrderId()); - - Application.applicationContext.getBean(fooddelivery.external.결제이력Service.class) - .결제(pay); - } -``` +시나리오는 단말앱(app)-->결제(pay) 시의 연결을 RESTful Request/Response 로 연동하여 구현이 되어있고, 결제 요청이 과도할 경우 CB 를 통하여 장애격리. - Hystrix 를 설정: 요청처리 쓰레드에서 처리시간이 610 밀리가 넘어서기 시작하여 어느정도 유지되면 CB 회로가 닫히도록 (요청을 빠르게 실패처리, 차단) 설정 ```