Spring Cloud를 활용한 MSA 기초

모놀리틱 아키텍쳐 (Monolithic architecture)

  • HA(High Availability) 구성 : 지속적으로 구동되는(uptime) 시스템
  • LoadBalancer : L4 switch(hardware), L7(Nginx, HAProxy)
  • 콘웨이의 법칙(Conway’s Law) : 모든 조직은 조직의 의사소통 구조(communication structure)와 똑같은 구조를 갖는 시스템을 설계.
    콘웨이의 법칙은 조직도에 초점을 두지 않고, 실질적인 소통관계에 관심을 둔다. 너무 많은 통신관계를 갖는 것은 프로젝트에 진정한 위험이 됨.
  • 장점 :
    1. 개발 단순 (repository 하나)
    2. 배포 단순 (war 하나)
    3. scale-out 이 단순( server 하나) 하지만, DB 성능으로 인한 한계
  • 단점 :
    1. 무거움
    2. 어플리케이션 시작시간이 오래걸림
    3. 기술 스택 바꾸기 힘듬
    4. 높은 결합도
    5. 코드베이스의 책임 한계와 소유권이 불투명

마이크로서비스 아키텍쳐 (MSA; Micro Service Architecture)

  • 시스템을 여러개의 독립된 서비스로 나눠서, 이 서비스를 조합함으로서 기능을 제공하는 아키텍쳐 디자인 패턴
  • 각 서비스 간 network를 통해, 보통 HTTP를 통해 연동
  • 독립된 배포 단위
  • 각 서비스는 쉽게 교체 가능
  • 각 서비스는 기능중심으로 구성됨 ex) 프론트엔드, 추천, 정산, 상품 등
  • 각 서비스는 적합한 프로그래밍 언어, 데이터베이스, 환경으로 만들어진다.
  • 서비스는 크기가 작고, 상황에 따라 경계를 정하고, 자율적으로 개발되고, 독립적으로 배포되고, 분산되고, 자동화 된 프로세스로 구축되고 배포된다.

Cloud Native

  • 애플리케이션을 어떻게 만들고 배포하는지에 있으며, 위치는 중요하지 않다.
  • 특징 : 신축성(Resiliency), 민첩성(Agility), 확장 가능성(Scalable), 자동화(Automation), 무상태(State-less)

Twelve-Factors

  • Heroku 클라우드 플랫폼 창시자들이 정립한 애플리케이션 개발 원칙 중 유익한 것을 모아서 정리한 것
  • 탄력적(elastic)하고, 이식성 있는(portability) 배포를 위한 베스트 프랙티스(Best Practices)
  • 12가지 제약조건
    1 코드베이스 단일 코드베이스. 버전 관리되는 하나의 코드베이스와 다양한 배포. 개발/테스트/ 운영서버(인스턴스)는 동일한 코드기반이어야 함
    2 의존성 명시적으로 선언되고 분리된 의존성. 필요한 의존성을 애플리케이션과 함께 담음
    3 설정 환경설정은 분리하여 외부에 보관. 소스코드(코드베이스)는 하나, 환경(개발/테스 트/운영)에 따라 설정만 바꿔야 함
    4 백엔드 서비스 백엔드 서비스를 연결된 리소스로 취급. URL을 통해 접근(바인딩)되어야 함
    5 빌드, 릴리즈, 실행 분리된 빌드와 실행 단계를 가져야 함
    6 무상태 프로세스 애플리케이션을 하나 혹은 여러개의 무상태 프로세스로 실행. 상태는 외부저장소 에 보관
    7 포트 바인딩 포트 바인딩을 사용해서 서비스 노출. 별도의 웹서버를 두지 않고 자기완결적으로 서비스 제공
    8 동시성 프로세스 모델을 사용한 확장(scale out). 프로세스가 복제를 통해 확장될 수 있 게 설계해야 함
    9 폐기 가능 빠른 시작과 그레이스풀 셧다운(graceful shutdown)을 통한 안정성 극대화
    10 dev/prod 일치 development, staging, production 환경을 최대한 동일하게 유지
    11 로그 로그를 이벤트 스트림으로 취급. 로컬서버에 저장하지 말고 중앙저장소로 수집
    12 Admin 프로세스 admin/maintenance 작업을 일회성 프로세스로 실행

Netflix OSS, Spring Cloud

Netflix OSS, Spring Cloud의 교집합(Spring-Cloud-Netflix) : Hystrix, Eureka, Ribbon, Zuul

Hystrix – Circuit Breaker

  • hystrix는 netflix에서 만든 라이브러리로 마이크로 서비스 아키텍처에서 분산된 서비스간 통신이 원활하지 않은 경우에 각 서비스가 장애 내성과 지연 내성을 갖게하도록 도와주는 라이브러리다.
  • Latency Tolerance and Fault Tolerance for Distributed Systems
  • Circuit Open? Circuit이 오픈된 Method는 (주어진 시간동안) 호출이 “제한”되며, “즉시” 에러를 반환한다.
  • Why? 특정 메소드에서의 지연 (주로 외부 연동에서의 지연)이 시스템 전체의 Resource 를 (Thread, Memory등)를 모두 소모하여 시스템 전체의 장애를 유발한다. 특정 외부 시스템에서 계속 에러를 발생 시킨다면, 지속적인 호출이 에러 상황을 더 욱 악화 시킨다.
  • So! 장애를 유발하는 (외부) 시스템에 대한 연동을 조기에 차단 (Fail Fast) 시킴으로서 나의 시스템을 보호한다.
  • 기본설정 10초동안 20개 이상의 호출이 발생 했을때 50% 이상의 호출에서 에러가 발생하 면 Circuit Open
  • Circuit이 오픈된 경우의 에러 처리는 ? – Fallback Fallback method는 Circuit이 오픈된 경우 혹은 Exception이 발생한 경우 대신 호출될 Method. 장애 발생시 Exception 대신 응답할 Default 구현을 넣는다.
  • 오랫동안 응답이 없는 메소드에 대한 처리 방법은 ? – Timeout 설정하지 않으면 default 1,000ms 설정 시간동안 메소드가 끝나지 않으면 (return / exception) Hystrix는 메소드를 실제 실행중인 Thread에 interrupt() 를 호출 하고, 자신은 즉시 HystrixException 을 발생시킨다. 물론 이경우에도 Fallback이 있다면 Fallback을 수행

Server Side LoadBalancer

  • hardware기반으로 비용 up, 유연성 down
  • 서버를 추가하기 위해서는 설정 필요
  • LoadBalancing Schema 이 한정적(Round Robbin, Sticky)

Client LoadBalancer – Ribbon

  • software기반으로 비용 down, 유연성 up
  • 서버를 추가하기 위해 변경이 자유로움(coding추가 필요)
  • LoadBalancing Schema 이 마음대로 구성가능(coding추가 필요)

Dynamic Service Discovery – Eureka

  • AWS와 같은 Cloud 시스템에서 서비스의 로드 밸런싱과 실패처리 등을 유연하게 가져가 위해 각 서비스들의 IP / Port / InstanceId를 가지고 있는 REST 기반의 미들웨어 서버

  • Eureka in Spring Cloud 서버 시작 시 Eureka Server(Registry)에 자동으로 자신의 상태를 등록(up) : eureka.client.register-with-eureka : true(default) 주기적 HeartBeat으로 Eureka Server에 자신이 살아 있음을 알림 : eureka.instance.lease-renewal-interval-in-seconds: 30(default) 서버 종료 시 Eureka Server에 자신의 상태 변경(down) 혹은 자신의 목록 삭제 Eureka 상에 등록된 이름은 ‘spring.application.name

Declarative Http Client – Feign

  • MSA 처럼 분산되어있는 시스템을 사용하는 입장에서는 API를 호출하는 코드를 노가다 식으로 항상 만들어줘야하는 번거로움이 생겼습니다. 이를 해결해 줄 수 있는 Spring Cloud 프로젝트가 바로 Feign입니다. Feign은 RestTemplate 호출 등을 JPA Repository 처럼 interface로 단순히 추상화 한 프로젝트입니다.
  • Interface 선언을 통해 자동으로 Http Client를 생성
  • RestTemplate 은 concreate 클래스라 테스트하기 어렵다
  • Spring Cloud 에서 Open-Feign 기반으로 Wrapping 한 것이 Spring Cloud Feign

Zuul – API Gateway

  • 모든 장비 또는 웹사이트에서 백엔드 서비스를 호출할 때 거치는 문 같은 역할을 하는 어플리케이션입니다. Edge 서비스 어플리케이션이라고도 하며 MSA에서 동적 라우팅, 모니터링, 보안 등을 담당
  • API Gateway 클라이언트와 백엔드 서버 사이의 출입문(front door) 라우팅(라우팅, 필터링, API변환, 클라이언트 어댑터 API, 서비스 프록시) 횡단 관심사 cross-service concerns 보안. 인증(authentication) , 인가(authorization) 일정량 이상의 요청 제한(rate limiting) 계측(metering)

  1. Zuul의 모든 API 요청은 HystrixCommand로 구성되어 전달 각 API 경로 (서버군) 별로 Circuit Breaker 생성 하나의 서버군이 장애를 일으켜도 다른 서버군의 서비스에는 영향이 없다. CircuitBreaker / ThreadPool의 다양한 속성을 통해 서비스 별 속성에 맞는 설정 가능
  2. API를 전달할 서버의 목록을 갖고 Ribbon을 통해 Load-Balancing을 수행한다. 주어진 서버 목록들을 Round-Robin으로 호출 Coding을 통해 Load Balancing 방식 Customize 가능
  3. Eureka Client를 사용하여 주어진 URL의 호출을 전달할 “서버 리스트”를 찾는다. Zuul에는 Eureka Client가 내장 각 URL에 Mapping된 서비스 명을 찾아서 Eureka Server를 통해 목록을 조회 한다. 조회된 서버 목록을 Ribbon 클라이언트에게 전달한다.
  4. Eureka + Ribbon에 의해서 결정된 Server 주소로 HTTP 요청 Apache Http Client가 기본 사용 OKHttp Client 사용 가능
  5. 선택된 첫 서버로의 호출이 실패할 경우 Ribbon에 의해서 자동으로 Retry 수행 Retry 수행 조건 Http Client에서 Exception 발생 (IOException) 설정된 HTTP 응답코드 반환 (ex 503)

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다