From 8fe6668ff49fc2153ecb43070859fdb10cb20975 Mon Sep 17 00:00:00 2001 From: Juyounglee95 Date: Thu, 23 Apr 2020 13:58:13 +0900 Subject: [PATCH] Update README.md --- README.md | 292 ++++++------------------------------------------------ 1 file changed, 32 insertions(+), 260 deletions(-) diff --git a/README.md b/README.md index 847d1d1..11f9733 100644 --- a/README.md +++ b/README.md @@ -154,8 +154,7 @@ https://github.com/Juyounglee95/view ## 헥사고날 아키텍처 다이어그램 도출 //////수정예정 -![image](https://user-images.githubusercontent.com/487999/79684772-eba9ab00-826e-11ea-9405-17e2bf39ec76.png) - +https://user-images.githubusercontent.com/18453570/80059618-5f95cd00-8567-11ea-9855-6fdc2e51bfd0.png - Chris Richardson, MSA Patterns 참고하여 Inbound adaptor와 Outbound adaptor를 구분함 - 호출관계에서 PubSub 과 Req/Resp 를 구분함 @@ -394,290 +393,63 @@ BookRentalSystem.java (Entity) 각 구현체들은 각자의 source repository 에 구성되었고, 사용한 CI/CD 플랫폼은 azure를 사용하였으며, pipeline build script 는 각 프로젝트 폴더 이하에 azure-pipeline.yml 에 포함되었다. +## pipeline 동작 결과 -## 동기식 호출 / 서킷 브레이킹 / 장애격리 +아래 이미지는 azure의 pipeline에 각각의 서비스들을 올려, 코드가 업데이트 될때마다 자동으로 빌드/배포 하도록 하였다. -* 서킷 브레이킹 프레임워크의 선택: Spring FeignClient + Hystrix 옵션을 사용하여 구현함 +![image](https://user-images.githubusercontent.com/18453570/79945720-6b22be80-84a9-11ea-8465-132806bc0f97.png) -시나리오는 단말앱(app)-->결제(pay) 시의 연결을 RESTful Request/Response 로 연동하여 구현이 되어있고, 결제 요청이 과도할 경우 CB 를 통하여 장애격리. +그 결과 kubernetes cluster에 아래와 같이 서비스가 올라가있는 것을 확인할 수 있다. -- Hystrix 를 설정: 요청처리 쓰레드에서 처리시간이 610 밀리가 넘어서기 시작하여 어느정도 유지되면 CB 회로가 닫히도록 (요청을 빠르게 실패처리, 차단) 설정 -``` -# application.yml +![image](https://user-images.githubusercontent.com/18453570/79971771-c2d42080-84cf-11ea-9385-0896baf668a4.png) -hystrix: - command: - # 전역설정 - default: - execution.isolation.thread.timeoutInMilliseconds: 610 +또한, 기능들도 정상적으로 작동함을 알 수 있다. -``` +**<이벤트 날리기>** -- 피호출 서비스(결제:pay) 의 임의 부하 처리 - 400 밀리에서 증감 220 밀리 정도 왔다갔다 하게 -``` -# (pay) 결제이력.java (Entity) +![image](https://user-images.githubusercontent.com/18453570/80060143-cb2c6a00-8568-11ea-934a-111ccd8c21c9.png) +![image](https://user-images.githubusercontent.com/18453570/80060146-ce275a80-8568-11ea-993a-9f206ed4e7e8.png) +![image](https://user-images.githubusercontent.com/18453570/80060149-d089b480-8568-11ea-83ef-8a2496163806.png) +![image](https://user-images.githubusercontent.com/18453570/80060153-d2537800-8568-11ea-8c01-0a4740373c4a.png) +![image](https://user-images.githubusercontent.com/18453570/80060164-d5e6ff00-8568-11ea-8f75-b8e735ba7e18.png) - @PrePersist - public void onPrePersist(){ //결제이력을 저장한 후 적당한 시간 끌기 +**<동작 결과>** - ... - - try { - Thread.currentThread().sleep((long) (400 + Math.random() * 220)); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } -``` +![image](https://user-images.githubusercontent.com/18453570/80060261-15ade680-8569-11ea-8256-d28b1e7f1e67.png) -* 부하테스터 siege 툴을 통한 서킷 브레이커 동작 확인: -- 동시사용자 100명 -- 60초 동안 실시 - -``` -$ siege -c100 -t60S -r10 --content-type "application/json" 'http://localhost:8081/orders POST {"item": "chicken"}' - -** SIEGE 4.0.5 -** Preparing 100 concurrent users for battle. -The server is now under siege... - -HTTP/1.1 201 0.68 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 0.68 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 0.70 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 0.70 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 0.73 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 0.75 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 0.77 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 0.97 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 0.81 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 0.87 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 1.12 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 1.16 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 1.17 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 1.26 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 1.25 secs: 207 bytes ==> POST http://localhost:8081/orders - -* 요청이 과도하여 CB를 동작함 요청을 차단 - -HTTP/1.1 500 1.29 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 500 1.24 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 500 1.23 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 500 1.42 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 500 2.08 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 1.29 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 500 1.24 secs: 248 bytes ==> POST http://localhost:8081/orders - -* 요청을 어느정도 돌려보내고나니, 기존에 밀린 일들이 처리되었고, 회로를 닫아 요청을 다시 받기 시작 - -HTTP/1.1 201 1.46 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 1.33 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 1.36 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 1.63 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 1.65 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 1.68 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 1.69 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 1.71 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 1.71 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 1.74 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 1.76 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 1.79 secs: 207 bytes ==> POST http://localhost:8081/orders - -* 다시 요청이 쌓이기 시작하여 건당 처리시간이 610 밀리를 살짝 넘기기 시작 => 회로 열기 => 요청 실패처리 - -HTTP/1.1 500 1.93 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 500 1.92 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 500 1.93 secs: 248 bytes ==> POST http://localhost:8081/orders - -* 생각보다 빨리 상태 호전됨 - (건당 (쓰레드당) 처리시간이 610 밀리 미만으로 회복) => 요청 수락 - -HTTP/1.1 201 2.24 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 2.32 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 2.16 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 2.19 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 2.19 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 2.19 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 2.21 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 2.29 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 2.30 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 2.38 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 2.59 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 2.61 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 2.62 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 2.64 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.01 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.27 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.33 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.45 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.52 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.57 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.69 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.70 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.69 secs: 207 bytes ==> POST http://localhost:8081/orders - -* 이후 이러한 패턴이 계속 반복되면서 시스템은 도미노 현상이나 자원 소모의 폭주 없이 잘 운영됨 - - -HTTP/1.1 500 4.76 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 500 4.23 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.76 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.74 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 500 4.82 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.82 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.84 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.66 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 500 5.03 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 500 4.22 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 500 4.19 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 500 4.18 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.69 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.65 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 5.13 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 500 4.84 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 500 4.25 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 500 4.25 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.80 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 500 4.87 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 500 4.33 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.86 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 500 4.96 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 500 4.34 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 500 4.04 secs: 248 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.50 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.95 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.54 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 4.65 secs: 207 bytes ==> POST http://localhost:8081/orders - - -: -: - -Transactions: 1025 hits -Availability: 63.55 % -Elapsed time: 59.78 secs -Data transferred: 0.34 MB -Response time: 5.60 secs -Transaction rate: 17.15 trans/sec -Throughput: 0.01 MB/sec -Concurrency: 96.02 -Successful transactions: 1025 -Failed transactions: 588 -Longest transaction: 9.20 -Shortest transaction: 0.00 - -``` -- 운영시스템은 죽지 않고 지속적으로 CB 에 의하여 적절히 회로가 열림과 닫힘이 벌어지면서 자원을 보호하고 있음을 보여줌. 하지만, 63.55% 가 성공하였고, 46%가 실패했다는 것은 고객 사용성에 있어 좋지 않기 때문에 Retry 설정과 동적 Scale out (replica의 자동적 추가,HPA) 을 통하여 시스템을 확장 해주는 후속처리가 필요. - -- Retry 의 설정 (istio) -- Availability 가 높아진 것을 확인 (siege) ### 오토스케일 아웃 -앞서 CB 는 시스템을 안정되게 운영할 수 있게 해줬지만 사용자의 요청을 100% 받아들여주지 못했기 때문에 이에 대한 보완책으로 자동화된 확장 기능을 적용하고자 한다. -- 결제서비스에 대한 replica 를 동적으로 늘려주도록 HPA 를 설정한다. 설정은 CPU 사용량이 15프로를 넘어서면 replica 를 10개까지 늘려준다: -``` -kubectl autoscale deploy pay --min=1 --max=10 --cpu-percent=15 -``` -- CB 에서 했던 방식대로 워크로드를 2분 동안 걸어준다. -``` -siege -c100 -t120S -r10 --content-type "application/json" 'http://localhost:8081/orders POST {"item": "chicken"}' -``` +- 포인트서비스에 대한 replica 를 동적으로 늘려주도록 HPA 를 설정한다. 설정은 CPU 사용량이 15프로를 넘어서면 replica 를 10개까지 늘려준다: - 오토스케일이 어떻게 되고 있는지 모니터링을 걸어둔다: -``` -kubectl get deploy pay -w -``` -- 어느정도 시간이 흐른 후 (약 30초) 스케일 아웃이 벌어지는 것을 확인할 수 있다: -``` -NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE -pay 1 1 1 1 17s -pay 1 2 1 1 45s -pay 1 4 1 1 1m -: -``` -- siege 의 로그를 보아도 전체적인 성공률이 높아진 것을 확인 할 수 있다. -``` -Transactions: 5078 hits -Availability: 92.45 % -Elapsed time: 120 secs -Data transferred: 0.34 MB -Response time: 5.60 secs -Transaction rate: 17.15 trans/sec -Throughput: 0.01 MB/sec -Concurrency: 96.02 -``` + +![image](https://user-images.githubusercontent.com/18453570/80059958-51947c00-8568-11ea-9567-1b7d69c7381f.png) + +- 워크로드를 2분 동안 걸어준 후 테스트 결과는 아래와 같다. + +![image](https://user-images.githubusercontent.com/18453570/80060025-8274b100-8568-11ea-8f60-fa428c62168c.png) ## 무정지 재배포 -* 먼저 무정지 재배포가 100% 되는 것인지 확인하기 위해서 Autoscaler 이나 CB 설정을 제거함 +Autoscaler설정과 Readiness 제거를 한뒤, 부하를 넣었다. -- seige 로 배포작업 직전에 워크로드를 모니터링 함. -``` -siege -c100 -t120S -r10 --content-type "application/json" 'http://localhost:8081/orders POST {"item": "chicken"}' +이후 Readiness를 제거한 코드를 업데이트하여 새 버전으로 배포를 시작했다. -** SIEGE 4.0.5 -** Preparing 100 concurrent users for battle. -The server is now under siege... +그 결과는 아래는 같다. -HTTP/1.1 201 0.68 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 0.68 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 0.70 secs: 207 bytes ==> POST http://localhost:8081/orders -HTTP/1.1 201 0.70 secs: 207 bytes ==> POST http://localhost:8081/orders -: - -``` - -- 새버전으로의 배포 시작 -``` -kubectl set image ... -``` - -- seige 의 화면으로 넘어가서 Availability 가 100% 미만으로 떨어졌는지 확인 -``` -Transactions: 3078 hits -Availability: 70.45 % -Elapsed time: 120 secs -Data transferred: 0.34 MB -Response time: 5.60 secs -Transaction rate: 17.15 trans/sec -Throughput: 0.01 MB/sec -Concurrency: 96.02 - -``` -배포기간중 Availability 가 평소 100%에서 70% 대로 떨어지는 것을 확인. 원인은 쿠버네티스가 성급하게 새로 올려진 서비스를 READY 상태로 인식하여 서비스 유입을 진행한 것이기 때문. 이를 막기위해 Readiness Probe 를 설정함: - -``` -# deployment.yaml 의 readiness probe 의 설정: +![image](https://user-images.githubusercontent.com/18453570/80060602-ec418a80-8569-11ea-87ea-34004c1ce5d3.png) +![image](https://user-images.githubusercontent.com/18453570/80060605-eea3e480-8569-11ea-9825-a375530f1953.png) -kubectl apply -f kubernetes/deployment.yaml -``` +다시 Readiness 설정을 넣고 부하를 넣었다. -- 동일한 시나리오로 재배포 한 후 Availability 확인: -``` -Transactions: 3078 hits -Availability: 100 % -Elapsed time: 120 secs -Data transferred: 0.34 MB -Response time: 5.60 secs -Transaction rate: 17.15 trans/sec -Throughput: 0.01 MB/sec -Concurrency: 96.02 +그리고 새버전으로 배포한 뒤 그 결과는 아래와 같다. -``` + +![image](https://user-images.githubusercontent.com/18453570/80060772-565a2f80-856a-11ea-9ee3-5d682099b899.png) +![image](https://user-images.githubusercontent.com/18453570/80060776-5823f300-856a-11ea-89a9-7c945ea05278.png) 배포기간 동안 Availability 가 변화없기 때문에 무정지 재배포가 성공한 것으로 확인됨. - -# 신규 개발 조직의 추가 - - ![image](https://user-images.githubusercontent.com/487999/79684133-1d6c4300-826a-11ea-94a2-602e61814ebf.png) - - -- 마케팅팀의 추가 - - KPI: 신규 고객의 유입률 증대와 기존 고객의 충성도 향상 - - 구현계획 마이크로 서비스: 기존 customer 마이크로 서비스를 인수하며, 고객에 음식 및 맛집 추천 서비스 등을 제공할 예정 - -- 이벤트 스토밍 - -추가된 조직에 따른