Spring Cloud 적용기

(hystrix, turbine, eureka, config)

이창용 / 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