[MSA] Spring Boot 를 사용한 마이크로서비스 구축 및 소개(2부)

min.c00·2023년 4월 2일
0

MSA + Spring Boot

목록 보기
2/7
post-thumbnail

마이크로 서비스 소개


이책은 스프링으로 하는 마이크로서비스 구축(스프링 부트와 스프링 클라우드를 이용한 도커/쿠버네티스 마이크로서비스) 책을 읽고 학습한 내용을 정리한 글입니다.

목차


  1. 마이크로서비스 디자인 패턴
    1-1. 서비스 검색(Service Discovery)
    1-2. 에지 서버(Edge Server)
    1-3. 리액티브 마이크로서비스(Reactive Microservice)
    1-4. 구성 중앙화(Cetral Configuration)
    1-5. 로그 분석 중앙화(Centralized Log Analysis)
    1-6. 분산 추적(Distributed Tracing)
    1-7. 서킷 브레이커(Circuit Breaker)
    1-8. 제어 루프(Control Loop)
    1-9. 모니터링 및 경고 중앙화(Centralized Monitoring and Alarm)
  1. 필수 소프트웨어

1. 마이크로서비스 디자인 패턴



1-1. 서비스 검색(Service Discovery)


✏️ 문제점: 클라이언트가 마이크로서비스와 그 인스턴스를 찾을 수 있어야 한다. 컨테이너 등에서 실행되는 마이크로서비스 인스턴스는 시작하면서 동적 IP주소를 할당 받는게 일반적이다. 이런 상황은 마이크로서비스가 노출하는 HTTP 기반의 REST API를 클라이언트에서 호출하는 것을 어렵게한다.

💡 해결책: 현재 사용 가능한 마이크로서브와 그 인스턴스를 추적하는 새 컴포넌트(서비스 검색 서비스)를 시스템 환경에 추가한다.

  • 해결책의 필요조건
    • 마이크로 서비스와 마이크로서비스 인스턴스를 자동으로 등록 및 등록 해지한다.
    • 클라이언트는 마이크로서비스의 논리 엔드포인트에 요청을 보낼 수 있어야 한다. 요청은 사용 가능한 마이크로서비스 인스턴스 중 하나로 라우팅된다.
    • 마이크로서비스에 대한 요청은 가용 인스턴스로 로드밸런싱돼야 한다.
    • 요청을 라우팅하지 않고자 상태가 비정상인 인스턴스를 감지할 수 있어야한다.

1-2. 에지 서버(Edge Server)


✏️ 문제점: 마이크로서비스 시스템 환경에선 일부 바이크로서비스만 시스템 환경 외부에 공개하고, 그 외의 마이크로서비스는 외부에서 접근하지 못하도록 숨기는 게 바람직하다. 공개된 마이크로서비스는 악의적인 클라이언트의 요청으로부터 보호해야한다.

💡 해결책: 모든 요청이 거치는 시스템 환경에 새 컴포넌트(에지 서버)를 추가한다.

  • 해결책의 필요 조건
    • 외부로 공개하면 안 되는 내부 서비스는 숨긴다. 즉 외부 요청을 허용하는 마이크로서비스로만 요청을 라우팅한다.
    • 서비스를 외부로 공개하되 악의적인 요청으로부터 보호한다. 즉 표준 프로토콜과 OAuth, OIDC, JWT토큰, API키 등의 모범 사례를 사용해 신뢰할 수 잇는 클라이언트인지 확인한다.

1-3. 리액티브 마이크로서비스(Reactive MSA)


✏️ 문제점: 관례적으로 자바 개발자는 HTTP기반의 RESTful JSON API와 같은 블로킹 I/O모델을 사용해 동기식 통신을 구현해 왔다. 블로킹 I/O를 사용하면 요청을 처리하는 동안 운영체제의 스레드를 점유하게 된다. 동시 요청 수가 증가하거나 요청과 관려된 컴포넌트가 증가하면 운영체제의 가용 스레드가 부족해 응답 시간이 늦어지거나 서버가 중단되는 문제가 발생할 수 있다.

💡 해결책: 논블로킹 I/O를 사용해 데이터베이스나 다른 마이크로서비스가 처리하길 기다리는 동안 스레드가 할당되지 않게 한다.

  • 해결책의 필요조건
    • 가능하다면 비동기 프로그래밍 모델을 사용한다. 즉 메시지를 보낸 후 수신자가 메시지를 처리하길 기다리지 않는다.
    • 동기식 프로그래밍 모델을 선호한다면 논블로킹 I/O를 사용해 응답을 기다리는 동안에도 스레드 할당 없이 동기실 요청을 실행하는 리액티브 프레임워크를 사용한다.
    • 마이크로서비스는 의존하는 서비스가 중단되라도 응답할 수 있도록 탄력성 있게 설계돼야 하며, 중단된 서비스가 재개되면 클라이언트가 서비스를 다시 사용할 수 있어야 한다. 이것을 자가 치유라고 한다.

1-4. 구성 중앙화(Central Configuration)


✏️ 문제점: 일반적으로 애플리케이션은 여러 환경변수나 파일에 담긴 구성정보와 함께 배포되는데, 다수의 마이크로서비스 인스턴스가 배포된 마이크로서비스 아키텍처 기반의 시스템 환경에선 문제가 있다.

  1. 실행 중인 모든 마이크로서비스 인스턴스의 구성 정보를 한눈에 보려면 어떻게 해야하는가?
  2. 구성을 업데이트하고 관련된 모든 마이크로서비스 인스턴스가 올바르게 업데이트 되게 하려면 어떻게 해야하는가?

💡 해결책: 시스템 환경에 모든 마이크로서비스의 구성 정보를 젖장하는 새 컴포넌트(구성 서버)를 추가한다.

  • 해결책의 필요조건
    • 마이크로서비스 집합에 대한 구성 정보를 한 곳에 저장하고 환경별(예: dev, test, aq, prod) 설정을 지원한다.

1-5. 로그 분석 중앙화(Centralized Log Analasis)


✏️ 문제점: 보통 애플리케이션을 실행하고 있는 로컬 머신에 애플리케이션 로그 이벤트를 기록하는데, 여러 개의 소규모 서버에 다수의 마이크로서비스 인스턴스를 배포하는 마이크로서비스 아키텍처 기반의 시스템 환경에선 다음과 같은 문제가 있다.

  1. 각 마이크로 서비스 인스턴스가 로컬에 로그 파일을 기록하는 상황에서 전체 시스템 환경에서 발생하는 사건을 개괄하려면 어떻게 해야 하는가?
  2. 문제가 발생한 마이크로서비스 인스턴스를 찾아서 로그 파일에 오류 메시지를 쓰게 하려면 어떻게 해야하는가?
  3. 최종 사용자가 문제를 보고했을 때 이와 관련된 로그 메시지를 찾으려면 어떻게 해야 하는가? 문제의 근본 원인이 되는 마이크로서비스 인스턴스를 찾으려면 어떻게 해야하는가?

💡 해결책: 로그를 중앙화해 관리하고 다음과 같은 기능을 갖춘 새 컴포넌트를 추가한다.

  1. 새 마이크로 서비스 인스턴스를 감지해 로그 이벤트를 수집한다.
  2. 로그 이벤트를 해석해 구조적이고 검색 가능한 형식으로 중앙 데이터베이스에 저장한다.
  3. 로그 이벤트를 조회 및 분석하기 위한 API와 그래픽 도구를 제공한다.

1-6. 분산 추적(Distributed Tracing)


✏️ 문제점: 시스템 환경에 대한 외부 호출을 처리하는 동안 마이크로서비스 사이에서 흐르는 요청 및 메시지를 추적할 수 있어야 한다.

예:

  1. 최종 사용자가 특정 장애에 대한 해결을 요청했을 때 문제를 일으킨 마이크로서비스를 찾고 근본 원인을 밝히려면 어떻게 해야하는가?
  2. 특정 엔티티와 관련된 문제를 지원하고자 이와 관련된 모든 로그 메시지를 찾고 싶다. 예를 들어 어떤 주문 번호에 대한 문제가 발생했을 때 해당 주문의 처리에 관여한 모든 마이크로서비스의 로그 메시지르를 찾으려면 어떻게 해야하는가?

💡 해결책: 공조 마이크로서비스 사이의 처리 과정을 추적하려면 관련된 모든 요청 및 메시지에 상관 ID(correlation ID)를 넣어야 하고, 모든 로그 이벤트에 상관 ID가 있어야한다. 중앙화된 로깅 서비스에서 상관 ID를 검색하면 관련된 로그 이벤트를 모두 찾을 수 있다. 비즈니스 관련 식별자(예: 고객, 제품, 주문 등)가 포함된 로그 이벤트를 찾은 다음 상관 ID로 검색하면 해당 비즈니스 식별자와 관련된 모든 로그 이벤트를 찾을 수 있다.

  • 해결책의 필요조건
    • 모든 수신 요청고 ㅏ이벤트에 고유 상관 ID를 할당한다. 상관 ID는 헤더와 같이 찾기 쉬운 위치에 넣는다.
    • 마이크로서비스에서 외부로 요청이나 메시지를 보낼 때는 요청과 메시지에 상관 ID를 꼭 넣는다.
    • 모든 로그 이벤트에는 사전에 정의한 형식의 상관 ID가 있어야 한다. 중앙화된 로깅 서비스는 로그 이벤트에서 상관 ID를 추출해 검색할 수 있다.

1-7. 서킷 브레이커(Circuit Breaker)


✏️ 문제점: 동기 방식으로 상호 통신하는 마이크로서비스 시스템 환경은 연쇄 장애가 발생할 여지가 있다. 하나의 마이크로서비스가 응답하지 않으면 이 마이크로서비스의 클라이언트 또한 클라이언트의 요청에 응답하지 않게 된다. 이 문제는 시스템 환경 전체에 재귀적으로 전파돼 중요한 부분까지 중단시킬 수 있다. (이런 문제는 블로킹 I/O를 사용해 동기식 요청을 실행하는 경우에 자주 발생한다.)

💡 해결책: 대상 서비스에 문제가 있다는 것을 감지해 새 요청을 보내지 않도록 차단하는 서킷 브레이커를 추가한다.

  • 해결책의 필요조건
    • 서비스에 문제가 감지되면 시간 초과를 무시하고 바로 실패하도록 서킷을 연다.
    • 반열림 서킷이라고도 하는 장애 복구용 프로브(probe)를 사용한다. 즉 서비스가 정상 동적하는지 확인하고자 주기적으로 요청을 보낸다.
    • 프로브가 서비스의 정상 동작을 감지하면 서킷을 닫는다. 이런 시스템 환경을 탄력적으로 만들어서 자가 치유를 가능하게 하는 매우 중요한 기능이다.

1-8. 제어 루프(Control Loop)


✏️ 문제점: 다수의 마이크로서비스 인스턴스가 여러 서버에 분산돼 있는 시스템 환경에선 중단되거나 지연된 마이크로서비스 인스턴스를 수동으로 감지하고 대처하는 것이 어렵다.

💡 해결책: 시스템 환경의 상태를 관찰하는 새 컴포넌트(제어 루프)를 시스템 환경에 추가한다. 이 컴포넌트는 운영자가 지정한 상태와 실제 상태를 지속적으로 관찰하며, 두 상태가 다른 경우에는 현재 상태가 지정한 상태와 일치하도록 조치를 취한다.

  • 해결책의 필요조건
    • 컨테이너를 기반으로 하는 환경에선 쿠버네티스와 같은 컨테이너 오케스트레이터로 이패턴을 구현한다.

1-7. 서킷 브레이커(Circuit Breaker)


✏️ 문제점: 동기 방식으로 상호 통신하는 마이크로서비스 시스템 환경은 연쇄 장애가 발생할 여지가 있다. 하나의 마이크로서비스가 응답하지 않으면 이 마이크로서비스의 클라이언트 또한 클라이언트의 요청에 응답하지 않게 된다. 이 문제는 시스템 환경 전체에 재귀적으로 전파돼 중요한 부분까지 중단시킬 수 있다. (이런 문제는 블로킹 I/O를 사용해 동기식 요청을 실행하는 경우에 자주 발생한다.)

💡 해결책: 대상 서비스에 문제가 있다는 것을 감지해 새 요청을 보내지 않도록 차단하는 서킷 브레이커를 추가한다.

  • 해결책의 필요조건
    • 서비스에 문제가 감지되면 시간 초과를 무시하고 바로 실패하도록 서킷을 연다.
    • 반열림 서킷이라고도 하는 장애 복구용 프로브(probe)를 사용한다. 즉 서비스가 정상 동적하는지 확인하고자 주기적으로 요청을 보낸다.
    • 프로브가 서비스의 정상 동작을 감지하면 서킷을 닫는다. 이런 시스템 환경을 탄력적으로 만들어서 자가 치유를 가능하게 하는 매우 중요한 기능이다.

1-9. 모니터링 및 경고 중앙화(Centralized Monitoring and Alarm)


✏️ 문제점: 응답 시간이 하드웨어 자원 사용량이 지나치게 높은 경우 문제의 근본 원인을 찾는 게 매우 어렵다. 마이크로서비스별 하드웨어 자원 사용량을 분석할 수 있어햔다.

💡 해결책: 마이크로서비스 인스턴스가 사용하는 하드웨어 자원 사용량에 대한 메트릭을 수집하는 새 컴포넌트(모니터 서비스)를 시스템 환경에 추가한다.

프로메테우스에서 가져온 메트릭을 시각화한 그라파나 화면

  • 해결책의 필요조건
    • 오토스케일링된 서버를 포함해 시스템 환경에서 사용하는 모든 서버의 메트릭을 수집해야한다.
    • 서버에서 새로 시작된 마이크로서비스 인스턴스를 감지해 메트릭을 수집해야한다.
    • 수집한 메트릭을 조회 및 분석하기 위한 API와 그래픽 도로구를 제공해야한다.

2. 필수 소프트웨어


디자인 패턴스프링 부트스프링 클라우드쿠버네티스이스티오
서비스 검색넷플리스, 유레카(Eureka)와 넷플릭스 리본(Ribbon)쿠버네트스의 kube-proxy와 서비스 리소스
에지서버스프링 클라우드와 스프링 시큐리티, OAUTH(Spring Security OAuth)쿠버네트스의 인그레스 컨트롤러(Ingress Controller)이스티오의 인그레스 게이트웨이
리액티브 마이크로서비스스프링 리액터(Spring Reactor)와 스프링 웹 플럭스(Spring WebFlux)
구성 중앙화스프링 컨피그 서버(Spring Config Server)쿠버네트스의 컨피그 맵(ConfigMap)과 시크릿(Secret)
로그 분석 중앙화일래스틱 서치(Elasticsearch), 플루언티드(Fluentd), 키바나(Kibana)
분산추적스프링 클라우드 슬루스(Sleuth)와 집킨(Zipkin)예거(Jaeger)
서킷 브레이커Resilience4j이상감지(Outlier detection)
제어 루프쿠버네이스의 컨트롤러 매니저(controller manager)
모니터링 및 경고 중앙화그라파나와 프로메테우스키알리(Kiali), 그라파나, 프로메테우스

0개의 댓글