Spring Cloud 적용기
이창용 / Maps
Architecture

장애

장애
- 실시간버스에 장애발생
- 대중교통 길찾기시 버스에 대한 실시간정보를 담아야하므로 길찾기 응답지연
- 대중교통 API에 요청이 쌓여 대중교통 API로 장애 전파
장애극복
- 실시간버스의 장애 원인 해결
- 실시간버스에 장애가 발생하더라도 대중교통 API 서버는 길찾기에 영향을 받지않게
Netflix Hystrix

Netflix Hystrix
- Hystrix가 annotation이나 AOP를 사용하지 않은 이유
- https://github.com/Netflix/Hystrix/wiki/FAQ%20:%20General#can-annotations-be-used
- annotation 기반의 설정을 이용할수 있는 javanica 모듈 사용
- https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica
- spring-boot-starter-netflix-hystrix에 다 있음
spring-boot-starter-hystrix,
spring-boot-starter-netflix-hystrix
- Spring boot starter 사용시 2개의 의존성
- spring-boot 2 에선 netflix-hystrix 사용
- deprecated, please use spring-cloud-starter-netflix-hystrix
Netflix Hystrix

Netflix Hystrix
- 메서드에서 예외가 발생할 시 지정한 fallback 메서드 호출
- 한가지 유의할 점은 기존 메서드와 시그니처가 동일해야 함 (접근제어자는 상관없음. private 이어도 됨.)
execution.isolation.thread.timeoutInMilliseconds
hystrix 가 설정된 메서드의 타임아웃
circuitBreaker.requestVolumeThreshold
circuitbreaker가 열릴 최소 요청수 조건
Netflix Hystrix
circuitBreaker.sleepWindowInMilliseconds
circuitbreaker가 열렸을때 지속 시간
coreSize
hystrix가 사용할 thread pool 사이즈
"10초 동안 30번 이상의 요청이 있었고, 오류율이 50% 이상이면 1분간 서킷브레이커를 열겠다"
유의할점
- Isolation (Thread / Semaphore)
넷플릭스 문서에서는 굳이 Semaphore 를 사용하겠다면 비네트워크 환경에서 사용하라고함, Thread를 권장
- ThreadPool
넷플릭스 문서에서는 기본값 (10) 권장. 별생각없이 기본값 썼다가 낭패. 넷플릭스 문서에 coreSize 를 구하는 공식이 있긴하지만 성능테스트를 돌려보며 점진적으로 늘린 값을 사용
모니터링
- HystrixDashBoard 의존성을 추가하면 actuator를 통해 hystrix 모니터링 가능 (Actuator 역시 의존하고있어야함)

모니터링
- HystrixDashboard는 하나의 인스턴스에 대한 모니터링만을 보여줌
- 대중교통 API 는 현재 10대 서버를 사용중이므로 각각의 상태를 보기위해선 한대씩 확인해야함
- 전면장애가 발생했을때 1대 정도만 샘플링으로 모니터링해도 충분하다고 판단
이후
- 실시간버스에 장애가 발생했을때도 대중교통 API는 버텨내며 길찾기에는 장애가 발생하지않음
- 전면장애에서 부분장애로...
Turbine
- Hystrix 를 클러스터링하여 모니터링할 수 있도록 해주는 라이브러리
- 인스턴스 클러스터 정보는 Eureka 를 이용하여 파악하므로 eureka 서버를 구성해야함
- turbine 1.x 버전은 eureka 없이 할수있고, 2.x 버전부터 eureka가 필수라고하는데 다른애들 다 2.x 버전 사용하는데 turbine만 1.x 쓰고싶지않아서 eureka를 사용하는쪽으로 진행
Eureka
- turbine 만을 위한 구성이라 최소한으로 구성함
- org.springframework.cloud:spring-cloud-starter-netflix-eureka-server 의존성만 추가해주면 됨

Eureka
- Eureka 서버는 곧 Eureka 클라이언트이기때문에 이에 대한 설정만 해주면 끝
- defaultZone은 꼭 카멜로 적어주어야함!!!
- 서버가 자기자신이기때문에 localhost 로 적음

Turbine
- Turbine 의존성 추가해주고 @EnableTurbine 애노테이션만 달아주면 됨
- Eureka 클라이언트 의존성 추가하고 클라이언트임을 알리는 @EnableDiscoveryClient 애노테이션 추가

Turbine
- appConfig 에는 application name을 넣어주면 됨 (spring.application.name)
- Eureka 클라이언트이므로 eureka 서버 정보를 넣어줌

Hystrix-client
- Hystrix client 들은 eureka client 설정만 해주면 됨

Eureka
- Eureka 서버로 접속하면 이런 페이지가 반겨줌
- Hystrix client 들인 대중교통 API는 pubtrans, turbine 서버는 pubtrans-turbine

Cluster 모니터링
- Hosts가 복수개인걸 볼 수 있음

Spring Cloud Config
- 엔진의 AB 테스트 필요성 대두
- 2가지 버전의 길찾기 엔진이 구동되고, 사용자별로 다른 엔진을 보여주도록 설정
- AB의 비율을 즉각적으로 변경하기위해 잦은 설정 변경이 필요했음
Spring Cloud Config
- git repository에 설정파일을 올려두고, config server가 git repository의 설정을 읽어 각 client들에게 제공하는 방식

Spring Cloud Config Server
- config 서버는 git repository에 대한 정보만 설정해주면 끝


Spring Cloud Config Client
- application.yml 이 아니라 bootstrap.yml에 config 서버에 대한 설정을 해야함
- client가 구동될때 server를 호출해서 config를 얻고, 이후에는 로컬에 캐시해놓고 사용

Refresh
- 설정을 변경해야하는 경우 git repository에 올라가있는 설정을 변경
- config server는 별도로 건드릴것 없이 갱신됨
- config client는 actuator를 이용해 갱신 요청을 해야 갱신됨
- curl -X POST pubtrans.map.naver.com/actuator/refresh
- 갱신이 필요한 항목에 대해 @RefreshScope 애노테이션이 달려있어야함
Refresh
- HikariCP를 사용하고있는경우 refresh 할때 쌩뚱맞게 여기서 에러가 발생
- HikariCP도 refresh 가능하게 만들어줘야함(@RefreshScope 추가)
느낀점
- 정말 별다른 코드없는 서버 애플리케이션들이 많아진다.
- 이게 클라우드, MSA 감성?
- 최대한 애플리케이션을 적게 만들려고하다보니 오히려 삽질을 훨씬 많이 하게된 경향이 있다.
- 처음에 turbine을 별도 서버로 안빼고 대중교통 API 서버에 적용하려했는데 spring-restdocs test에서 에러가 발생해서 그냥 별도 서버로 뺐음.
- 유레카 서버 설정할때 defaultZone은 반드시 카멜로 써야한다.
- 처음에 AB 테스트 적용할때는 설정만 바꿔서 배포하면 되는데 굳이 이런거(spring cloud config)까지 해야하나 라는 생각이 있었는데 해보니까 신세계. 배포없이 설정을 바꿀수있다는건 엄청나다.
Spring Cloud 적용기
By changyong
Spring Cloud 적용기
- 218