이번에 회사사람들과 MSA 관련 스터디를 하기로 했다.
첫번째로는 이 영상 을 보고 얘기를 나눠 보기로 했다. 영상을 보고 정리 겸 올려본다.
1) 모놀리식 시스템 vs MSA
모놀리식 시스템은 시스템 구성 요소들이 하나로 통으로 돌아가는 것이다.
당연하게도 MSA 는 요소요소들을 하나씩 쪼개서 분리해놓은 것이고..
출처- Introduction to Monolithic Architecture and MicroServices Architecture
이게 약간 “음 그렇지~~” 싶은 말이긴 한데 정확히 감이 안온다.
내가 이해하기로는 MSA 구조에서는 사용자 인터페이스 이후의 기능별로 서비스 코드 구성이나 db 를 분리해놓고 사용한다는 것 같다.
그럼 뭐가 좋길래 그렇게 쓸까??
- 큰 서비스를 개발/운영할때 부담감이 적다. 개개별 파트가 잘못되면 다른 서비스까지 안되는 상황을 막을 수 있어서.
- 새로운 기술을 받아들이기 쉽다. 기존 있는 파트에 영향없이 새 파트에만 새로운 기술 사용해볼 수 있으니까 단점은 서비스간 디펜던시가 있는 경우 구조 구성하는게 까다롭다는점…? 사실 단점은 크게 다가오지 않는다.
장점이야 현재 모놀리식 어플리케이션을 운영중이니까 와닿는데 단점은 글쎄 ^^ …
2) 서버 분리를 어떻게 해야하지??
기존의 레거시와 같이 진행해나가는 방식 = hybrid
아무래도 기존 레거시 시스템이 너무 크면 당연히 작은 파트부터 해보는 하이브리드일 수 밖에요 ^^…
3) 사용한 툴
= Netflix OSS (open source software) + spring boot
Netflix OSS 가 제공하는 세가지 툴 1) Hystrix : 라이브러린데 장애 전파 방지 /resilience (장애가 나도 다시 회복되도록 하는것) 장점 -> java vm 만 있으면 그냥 상속받아서 사용할 수 있음 or 어노테이션/ 스프링의 디펜던시로 바로 적용 가능
hystrix 4가지 기능
thread isolation
메소드를 인터셉트하여 대신 실행한다. 여기서 설정값이 semaphore or thread 중 선택한다.
semaphore 는 메소드 실행하는 스레드를 분리하지 않는 대신에 스레드를 몇개씩 부여받아서 해당 개수 이상 요청 실행해야하면 fallback 이 일어난다.
thread 는 메인 스레드와 메소드 실행 스레드를 분리한다. 스위칭이 많은 경우 context 공유 에 있어서 이슈가 있을 수 있다. 관련 내용
circuit breaker
메소드 실행 성공/실패 발생 여부로 통계 기록하고 circuit open 여부 결정
실패할 경우 사용자가 제공한 메소드 대신 실행한다 (fallback)
특정시간 동안 종료 안되면 exception (timeout)
time out 기능 특별한 이유 = socket timeout 이런건 내가 원하는대로 실행되지 않고 너무 많은 레이어에서 timeout 설정 얽혀서 복잡해!
그럼 circuit open 이 무슨 뜻이지?
일정 시간동안 일정개수 호출 통계 > 일정 비율 이상 에러나면 circuit open 한다.
->이러면 메소드 호출해도 바로 exception 으로 튕겨버린다.
A -> B,c,d 서버 호출할때 B 만 안되면 B 만 막는다.
다시 닫히는 시점은 일정시간 경과후에 단한번 시도해서 되면 이때 서킷 닫는다.
—> 기본 설정: 10초간 20개 이상 호출 발생, 50% 이상 에러면 5초간 서킷 오픈
서킷 통계내는 단위는 commandKey 로 선언해서 묶을 수 있다.
-> 너무 작은단위로하면 기간 초동안 횟수 범위 안넘어서 안잡힐 수 있다.
Fallback은 서킷 오픈뿐아니라 timeout 등 어떤 종류의 exception 발생하면 무조건 난다.
그냥 어노테이션으로 메소드 이름 지정해놓고 정의해놓는다.
😈 HystrixBadRequestException 😈
파라미터를 잘못 넘기거나 사용자가 call 할때 오류가 나는 건 이걸로 처리해야한다.
-> 서버의 에러가 아니라 사용자 에러니까 카운트 오류 방지하기 위해서 이걸로 처리해야함
Timeout 은 서킷브레이커 단위로 할 수 있고 기본 시간이 너무 짧다.
Ribbon
로드발란싱하는 라이브러리
로드발란싱을 어플리케이션이 함으로써 L4 같은 하드웨어에 집착하던 것 더이상은 No…..
나중에 eureka 와 합쳐져서 굴러가는거 설명합니당
Eureka
DNS 기반이 아니라 서버가 자기 이름+ ip + port 등록하고 조회
서버 시작할때 유레카 서버에 자동으로 자신이 살아있다고 등록
지속적으로 서비스 체크를 해서 유레카 서버는 해당 리스트를 갱신한다. (다운되면 알아서 뺌)
Eureka + Ribbon 이면 서버 목록 이런거 직접 ribbon 에 등록할 필욯없어서 eureka 가 서버 목록 가져오고 알아서 살아있는지 체크하니까 복잡한 절차 없이 가능하다.
zuul API GATEWAY
- hystrix + ribbon + Eureka 섞여 있어서 채택함
zuul 에서는 기본 thread isolation 이 semaphore 이다.
configuration server
모든 서버에 컨피크 클라이언트 탑재하고 있어서
서버 시작할때 자동으로 각 서버의 컨피그 안에 들어가게 된다.
개개별 서버에 설정 배포할 필요없고 편리하다.
모니터링
서버간 trace 정보 전달은 http header 같은 프로토콜 헤더로 전달되는데 스레드가 바뀌면 컨텍스트 유지가 어렵다.
Spring cloud sleuth 라는게 있는데 호출시마다 trace 정보를 생성하고 log 에 남기거나 수집서버 (zipkin) 으로 전달해준다.
db 호출 구간은 이걸로 아노디서 spring AOP 사용해 sleuth api 를 인젝션 해줘서 정보 직접 생성한다.
소감
흠 내용이 어렵긴 한데 그냥 그런가보다 하게 된다.
아무래도 코드단으로 직접 만져본적이 없어서 대충 알겠다고 생각하는 거 같은데 하나도 모르는거겠지 😉
내가 허접임을 인정하고 앞으로 배워나가면 된다!!
코드를 좀 더 많이 만져봐야겠다. 눈으로만 보니까 자꾸 알고 있는거 같다.