티스토리 뷰

Log/.daily

Spring Camp 2018를 다녀와서

가그린민트 2018. 4. 23. 20:41

처음엔 뭐 이딴걸 주나 했는데 일요일 종일 주물럭거린 구데타마 스트레스볼


우연에 기대어 스프링캠프에 다녀왔다. 여러 컨퍼런스를 다니면서도 항상 추천을 받았던 곳이라 기대가 되기도했고, 현 회사에 재작년, 작년에 발표한 분이 계셔 궁금하기도 하고 그랬던듯 하다. 나는 Track A를 들었는데, 쿠팡/우아한형제들/11번가/IBM 순으로 진행되었고 전체를 아우르는 주제는 MSA였다. 

전체적인 인상은, MSA로의 이전에 대한 쿠팡의 고민과 노력, 배민찬 서비스의 단계적인 DDD 도입을 엿볼 수 있었고, 11번가의 세션은 좀더 실무적이었으며, IBM의 경우 최근 변화된 내부 분위기로 Spring cloud와 kubernetes에 대한 경험 공유 정도 인듯 하다. 행사는 이러한 세션과 이후 네트워킹 행사 두 단계로 진행되었는데, 네트워킹은 지난해 참여했던 DeveLove와 비교하면 공간과 음식만 제공되는 자유로운 분위기였다.(공간의 특성상 한번 앉은 이후로는 다른 사람들과 대화하지 못해 아쉬웠고, 혼자 온 사람들에 대한 배려가 부족하여 아쉬웠다. 나는 운 좋게도 관심있던 회사 메인 개발자 분들과 대화하게 되어 유익했다.) 후원한 곳이 적은지 부스도 빈약해보였지만, 참여한 회사들이 모두 알차게 준비한 흔적이 곳곳에 보였고, 각 세션들의 내용도 너무 만족스러웠다.



기조연설이었을까. 쿠팡 대표 분이 마이크를 잡았고, 쿠팡이 테크회사로서 물류시스템의 변혁을 위해 했던 노력과 결과를 소개했고, 자연스럽게 그 기반이 되었던 MSA(이 날의 주제)로 ‘lego’님의 발표로 이어졌다. (그 기반에 오픈소스의 도움을 크게 받았기에 이제는 무언가의 보답을 하고 싶었고 그 맥락에서 이번 행사를 준비하였고, 앞으로 기술 블로그 등도 할 계획이라고 하는데, 최근 삼성 밋업에서도 느꼈지만 이런 흐름이 트렌드인가 보다.)

쿠팡은 지금껏 기술적으로 3번의 큰 변곡점이 있었다고 한다. php에서 java로, monolithic에서 msa로, onpremise에서 public cloud(aws)로의 이전이었고, 듣기만해도 아찔해지는 migration을 5년동안 서비스 확장 과정에서 진행했을 쿠팡 개발자들에게 경외심이 생기는 순간이었다.

5년 전 쿠팡은 흔히 말하는 monolithic 그 자체였고, 이에 따른 단일 장애점, 작은 수정에도 전체 서비스 QA Testing, legacy의 가속화(side-effect를 알 수 없으니, 전체 복붙 후 공유), 부분적 scale out의 어려움, 배포시간의 기하급수적 증가 등의 문제가 발생했다.


5년전 쿠팡에서 쓰던 배포 깃발


이에 자칭 vitamin project가 진행되었는데, 이는 비즈니스 로직과 플랫폼 서비스 사이에 vitamin framework을 두는 구성이었다. 가령, MSA에서는 모든 서비스가 API 통신을 하는데 모든 api들에 http 요청등을 만들어야 하니, provider helper library를 만들어 각 팀에 제공하는 형태인 것이다. 이 과정에서 MSA로의 이전으로 그동안 강하게 트랜잭션으로 묶여 있던 서비스 의존성을 message queue로 해결하였다고 한다. (order -> message queue -> delivery (-> 실패 -> dead letter queue -> message queue -> delivery)) 이를 기반하는 시스템 중에 CMDB, Bolt2 등이 인상적이었다. CMDB(Configuration Management Database)는 각 Service, Intrastructure 등의 메타 정보를 관리하는 DB이고, Bolt2는 blue/green 배포(master -> (lock) rc branch에서 stage -> canary -> all 단계로 배포 한 후 삭제(unlock) -> master branch)를 하는 시스템이다. 마치 Netflix의 그런 것들을 국내의 회사가 자체적으로 개발하여 사용하고 있다는 것이 놀라웠고, 전 회사에서 각 서비스별 자산관리를 위한 플랫폼을 만드는 경험을 해보았기에 그런 완성도 높은 서비스를 만들어냈던데에 부럽기도 하였다. 각 서비스의 버저닝과 device별로 A/B 테스트가 가능하고 관리되는 모습, API gateway가 각 api spec 정보를 가지고 있어 각 서비스/팀별 현황 가시화 및 자동화(swagger codegen), traffic explosion(의존성있는 api들이 모두 장애)에 대해 traffic throttling 및 circuit breaker system이 장애 극복 등 SRE 조직의 성숙도를 엿볼 수 있었다. 현재 쿠팡의 고민은 MSA로 넘어온 시점에서의 테스팅과 dynamic properties라고 한다. 세션 후 질문은 3개의 변곡점에서 대표의 실천적 의지와 구체적 방안에 대한 것이었고, 일반론적 답변이 나왔는데(제약 안에서 도전하는 builder 팀과 운영을 하는 manager 팀을 두며, 쿠팡은 장기적으로 해야할 큰 것에 집중한다는 것) 이를 해냈다는데에 박수치고 싶었다.

두번째 세션은 ‘이벤트기반 분산시스템을 위한 여정’이란 주제로 배민찬의 박용권님께서 발표하셨다. 초기에 물류팀(엑셀을 잘하는) 사람들이 직접 배송장을 작성하던 물류시스템과 기존 시스템을 잇는 과정에서 DDD 적용에 대한 고민을 담았던 듯 하다. 그 해결책은 adapters 였다. 즉, 기존 시스템의 메시지를 물류시스템의 메시지로 변환해주는 작업을 담당하는 adpater를 두어, 멱등성을 보장하고(비동기로 SQS를 사용하였는데 SQS는 메시지가 중복해서 올 수 있어서), side-effect 및 기술부채 해결과 확장성 등을 확보할 수 있었다고 한다. DDD를 적용하는 과정은 크게 도메인 지식의 증가, 경계 발견, 시스템으로 확장으로 진행되었고, 처음엔 도메인 지식이 부족해 모듈을 통해 도메인 경계를 나누다보면 하나의 JVM위에 올라온 모듈을 micro service라고 할 수 있지 않을까하여 묶었다고 한다. 그리고 모듈을 묶을 때는 (Component의 계층, 패턴에 따라 묶는 것이 아니라,) 도메인 경계에 따라 나눠 bounded context를 적용해보고 싶었다고 한다. 하지만 모듈간의 직접 참조로 개발되니 결합성이 증가되었고 이에 이벤트기반 아케텍처로 전환하였다고 한다. 모듈들이 점차 도메인 이벤트 기반으로 통합되자, 이제는 모듈의 행위에 대한 고민을하며 경역학, ERP 등 도메인 지식들을 깊이있게 학습하기 시작하셨다고… bonded context를 통합하는 과정에서 RPC (공유된 라이브러리가 필요하여 시스템간 결합도가 급격히 증가), Restful API(장애 전파에 대한 고민, 트랜잭션에 대한 고민), Messaging(RPC나 REST보다 견고하며 비동기라 시스템간 결합도를 낮추지만, 시스템이 많아지고 주고받는 메시지가 많아질수록 시스템 전체 작업을 파악하기가 어려워짐) 등의 방법이 있는데, 데이터를 실시간으로 가져가는 구간에서는 REST, 실제 작업이 이루어지는 구간은 messaging이 좋다고 한다. 그리고 배민찬은 AWS SNS + SQS 조합의 메시징 시스템을 활용하고 있다고 한다.(kafka는 운영을 위한 전담인력 배치가 어렵고, kinesis는 메시지량에 따른 자동화된 확장방식이 아니어서 적용하기에 러닝커브가 있었으며, amazon mq는 한국리전에 없었기 떄문에..SQS는 점대점 방식이라 SNS와 조합하여..) 그리하여 도메인 이벤트를 메시지에 담아 보내는 한편 서비스는 특정 메시지에만 관심이 있으니, adaper가 과도한 메시지가 돌아다니지 않도록 필터역할을 하도록 구성하였다고 한다. 현재 이벤트 모니터링은 감사와 보상 프로세스에 기인하는데 이에 대한 개선과 데이터 일관성 확보 등에 대한 고민 등이 남아있는 듯하다. 이번에 공유된 slideshare는 다시 정독해봐야겠다. 정말 좋은 발표였다.

다음 세션인 11번가의 MSA는 솔직히 잘 흡수가 되지 않았다. 그래도 hystrix, ribbon, eureka를 간접적으로나마 접할 수 있어서 좋았다. 그리고 IBM 세션은 이미 너무 지쳤던터라 집중을 할 수가 없었다. 이 두 세션 내용은 당일 기록했던 내용과 사진만 첨부하는것으로.. 회고하는 것도 지치네 ㅠ.ㅠ

200만 라인의 공통모듈.. 급격한 버전업은 전사장애로..?
db flag로 switchable하게..
legacy 코드에서는 새로운 api 서버들을 호출..
best practive ? netflix::oss
개발친화도 ? spring boot
oss -> spring cloud로 이전 (hystrix, ribbon, eureka)
hystrix : 장애전파방지 & resilience
circuit break / fall back / thread isolation / timeout
hystrix 적용 : annotation 사용 혹은 hystrixCommand 상속
hystrix command를 호출할때 벌어지는 일
1. 메소드를 intercept하여 대신 실행
2. exeception 발생여부를 기록하고 통계 -> circuit breaker
3. fallback
4. timeout
circuit breaker
일정시간동안 일정개수 이상의 호출이 발생할 경우 일정비율 이상의 에러가 발생하면 circuit open(호출차단)
(4) 일정시간 후에 단 한개의 요청에 대해서 호출을 허용하며(half open) 성공하면 circuit close (호출 허용)
hystrix.command.<commandKey>

circuit breaker 단위 CommandKey 단위로 통계를 내고 동작
fallback
fallback으로 지정된 메소드는 다음의 경우 원본 메소드 대신 실행
circuit open / any exception / 세마포어 혹은 threadpollrejection / timeout

hystrixBadRequestException
이 오류는 fallback을 실행하지 않으며 circuit open을 위한 통계에도 집계 X
timeout
circuit breaker 단위(commandKey단위로) timeout 설정 가능
default 값이 매우 짧음(1초)
isolation
- 세마포어
    전체 시스템의 장애로 번지는것을 막음
- thread
    thread pool 단위로 메소드 실행 (세마포어와 같은 장점) / 실제 메소드의 실행은 다른 thread에서 실행되므로 Thread Local 사용시 주의 ..
Ribbon
Netlix가 만든 LB를 내장한 RPC library

Spring cloud에서는 리본클라이언트를 사용자가 직접 사용하지 않음
- spring cloud의 http 통신이 필요한 요소에 내장되어 있음
 @LoadBalanced

기존 LoadBalancer와 다른 점
programmable함 
BeanType으로..
API Gateway
자체개발 vs Zuul
zuul - spring cloud 와 integration이 잘되어 있어서.. ㅠ.ㅠ
circuitbreaker는 commandKey 단위로 동작하잖아..
zuul에서 commandKey는 각 서버군 이름이 사용됨
zuul은 세마포어 isolation이 기본 -> 특정 api 군의 장애(지연)이 zuul 자체의 장애로 이어지지 않음
useSeprateThreadPools



api간 호출
----
so 리본과 유레카 조합으로 p to p 호출하기로..
- @LoadBalanced RestTemplate  -> 기존 rest template이 리본 + 유레카 기능을 갖게됨
(bean으로 선언된 것만 적용 가능)
- spring cloude feign
// commandKey : 각 메소드 단위로 생성
// ThreadPoolKey : 서버군 별로 생성
// 물론 configuration도 가능
장애 case
1. 한 대의 api server down
- 리본이 제일 먼저 반응 (retry)
- 유레카 서버에서 해당 instance 목록이 사라짐
- 3대중 1대가 down되었다면 에러비율은 33% so hystrix 설정이 50%로였다면 circuit은 오픈안됨, 단 timeout, isolation, fallback은 동작하여 적절할 조치

2. 특정 API 한개가 이상이 생긴다면.. appendix
spring cloud는 git 기반으로 config 관리 /  config들이 propertySource로 등록됨
config 파일들은 다양하게 구성 가능 (전체 / 서버군 / 특정 서버)
모니터링

zipkin, turbine, grafana..
api 호출에 많은 서버를 거침 -> 분산tracing 도입 필요
protocol 의 헤더를 통해 전달 가능(HTTP Header)
Thread localThread 정보를 넣는 것은 Hystrix, RXjava, @Async 등 Thread 변화가 일어날 가능성이 높음
Sleuth / Distributed Tracing 솔루션
 -> Logging (Application 로그에 Trace ID(UUID)가 함께 출력)
Sleuth with Zipkin (시각화) 
DB 쪽은 SPring AOP로 sleuth api로 trace 정보를 직접 생성
spring boot admin?
유레카에 등록되어 있는 모든 서버 정보를 표시/제어
spring boot actuator를 호출
오픈소스 | 소스코드가 주어졌기에 무엇이든 할 수 있다는 자신감 | 성장 | bug report 는 사용자의 몫

MSA를 위한 Spring Cloud와 Kubernetes

12 facotrs
클라우드 애플리케이션 개발 방법론 https://12factor.net/ko
동시성 / 폐기가능성(resiliency) (graceful shutdown) => scale out
spring cloud - msa를 위한 software의 집합군
kubernetes  특징
automatic binpacking
self-healing
horizontal scaling
service discovery and lb
automatic rollouts and rollbacks
secret and configuration management
storage orchestration
batch execution


'Log > .daily' 카테고리의 다른 글

180603 일상  (0) 2018.06.03
180513 일상  (2) 2018.05.14
180416 일상  (2) 2018.04.16
180218 일상  (0) 2018.02.19
180212 일상  (0) 2018.02.12
댓글
링크
최근에 달린 댓글
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Total
Today
Yesterday