[MSA스터디] 1. 마이크로서비스 소개

vector13·2022년 9월 20일
0

마이크로서비스의 특징 : 확장성, 탄력성, 관리 편의성

저자의 마이크로서비스 경험 소개

🐵독립적인 소프트웨어 컴포넌트 != 정통적인 일체형 애플리케이션

고객이 플랫폼에서 사용하려는 기능 쉽게 찾아 선택할 수 있도록 각 기능은 독립적인 소프트웨어 컴포넌트로 개발 ==> 각 컴포넌트는 자체 데이터 저장소가 있었고, 다른 컴포넌트와는 명확한 API로 통신 (( 플랫폼은 고객의 요구 사항에 맞춰서 하나 혹은 여러 개의 서버에 배포할 수 있음))

독립 소프트웨어 컴포넌트의 장점

플랫폼 기능을 독립적인 소프트웨어 컴포넌트로 나눴을 때의 장점

  • 고객은 플랫폼의 일부분만을 자체 시스템 환경에 배포, 명확한 api를 사용해 기존 시스템과 통합
  • 플랫폼 기능의 일부를 고객의 시스템 환경에 있는 기존 구현으로 대체하는 선택을 할 수 있음
  • 플랫폼의 각 컴포넌트는 개별적으로 배포, 업그레이드 가능 (b/c api 명확, 다른 컴포넌트 수명 주기와 상관없음)
  • 플랫폼의 각 컴포넌트를 다른 컴포넌트와 상관 없이 여러 서버로 scale out 가능 (b/c 명확한 API를 사용)

독립 소프트웨어 컴포넌트의 문제

  • 컴포넌트의 새 인스턴스를 추가시 -> 로드 밸런서 구성 필요 (수동) ==> 시간, 오류 발생
  • 통신하는 다른 시스템에서 오류 발생시 -> 플랫폼으로 전이됨 ==> 연쇄 장애
  • 모든 컴포턴트 인스턴스 구성을 일관성있게 최신상태 유지작업 -> 품질 문제 야기
  • 플랫폼 상태 모니터링 작업의 복잡정도 >>>>> 일체형 애플리케이션의 인스턴스 하나를 모니터링하는 것

대부분의 문제점은 자체 개발 도구와 수동 처리를 위한 문서화된 지침으로 해결 가능.

마이크로서비스 입문

처음에 일체형 애플리케이션으로 개발
-> 일체형 애플리케이션을 유지보수하고 개선 하는게 어려워짐 + 수직 스케일링(vertical scaling)의 한계 (== 가용한 최고 사양의 머신이 가진 성능을 넘어서 스케일링해야 한다는 난제 )
-> 스케일링할 수 있는 작은 컴포넌트로 나누는 방식으로 전환하기 시작
(cf. 앞단에 로드 밸런서를 배치하고 여러 개의 소형 서버에 작은 컴포넌트를 배포하면 수평 스케일링이 가능)

==> 결국 확장을 위해서 마이크로서비스를 선택

마이크로서비스 개발 및 MSA 문제 해결 오픈 소스 도구와 프레임워크

  • 스프링 클라우드 : 동적 서비스 검색과 구성 관리, 분산 추적, 서킷 브레이커 등의 기능 제공
  • 도커 : 컨테이너 엔진을 사용하면 개발 환경과 상용 환경 사이의 간격을 최소화
  • 아마존 ECSAmazon ECS, 하시코프 노마드HashiCorp Nomad, 쿠버네티스Kubernetes : 컨테이너를 실행하고 여러 대의 서버로 확장하는 고가용성을 지원하고 컴퓨팅 자원을 추가할 수 있는 도구

마이크로서비스 정의

마이크로서비스의 목표

  1. 빠르게 개발해 지속적으로 배포
  2. 수동 혹은 자동으로 쉽게 스케일링 가능

이를 위해 일체형 애플리케이션을 작은 컴포넌트로 나누는 것

마이크로서비스는 기본적으로 독자적인 업그레이드와 스케일링이 가능한 독립 소프트웨어 컴포넌트다.

마이크로서비스 조건

  1. 아무것도 공유하지 않는 아키텍처를 유지 == 마이크로서비스는 데이터베이스의 데이터를 공유X
  2. 명확한 인터페이스를 통해서만 통신(동기 서비스나 api이용한 메시징 방식)
  3. 개별적인 런타임 프로세스로 배포
  4. 상태없는 stateless 로 마이크로서비스 인스턴스 만든다. == 모든 마이크로서비스 인스턴스가 마이크로서비스로 들어오는 요청을 처리

마이크로서비스의 문제

  • 연쇄장애 : 동기식 통신을 사용하는 다수의 소형 컴포넌트는 연쇄 장애 유발 가능 (부하 높은 상황에서 특히)
  • 다수의 소형 컴포넌트를 최신 상태로 유지가 어려움
  • 많은 컴포넌트가 처리에 관여하는 요청은 추적이 어려움
  • 컴포넌트 수준의 하드웨어 자원 사용량 분석 어려움
  • 다수의 소형 컴포넌트를 수동 구성 / 관리하는 건 비용이 많이 들고 오류발생 가능성도 높다.
  • 애플리케이션을 독립 컴포넌트 그룹으로 나누면 분산 시스템을 형성하게 된다 === 분산 시스템은 본질적으로 다루기가 매우 어렵다

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

디자인 패턴을 사용해 앞 절에서 설명한 마이크로서비스 문제를 완화하는 방법을 설명
(책 뒤에서는 스프링 부트, 스프링 클라우드, 쿠버네티스를 사용해 이런 디자인 패턴을 구현하는 방법 )

1 서비스 검색

service discovery

1-1 문제

실행되는 마이크로서비스 인스턴스는 시작하면서 동적 IP 주소를 할당 받는 게 일반적인데 클라이언트가 마이크로서비스와 그 인스턴스를 찾을 수 있어야 한다는 문제를 가지고 있다.

1-2 해결

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

1-3 해결의 조건

  • 마이크로서비스와 마이크로서비스 인스턴스를 자동으로 등록/등록해지
  • 클라이언트는 마이크로서비스의 논리 endpoint에 request 보냄 -> 사용 가능한 마이크로서비스 인스턴스 중 route
  • 마이크로서비스에 대한 request 가용 인스턴스로 로드 밸런싱
  • 요청을 라우팅하지 않고 상태가 비정상인 인스턴스를 감지 가능해야함

구현의 전략
1. 클라이언트 측 라우팅: 클라이언트는 '서비스 검색 서비스'와의 통신을 지원하는 라이브러리를 사용 -> 요청을 보낼 만한 인스턴스를 찾아 보냄
2. 서버 측 라우팅: 서비스 검색 서비스의 인프라는 모든 request을 전달하는 reverse proxy를 노출 -> 클라이언트를 대신해 적절한 마이크로서비스 인스턴스로 요청 전달

2 에지 서버

1-1 문제

공개된 마이크로서비스는 악의적인 클라이언트의 요청으로부터 보호필요
일부 마이크로서비스만 시스템 환경 외부에 공개 + 그외는 외부 접근 못하게 숨겨야함

1-2 해결

모든 요청이 거치는 시스템 환경에 새 컴포넌트(에지 서버)를 추가
( 일반적으로 에지 서버는 리버스 프록시로 동작, 동적 로드 밸런싱 기능 제공을 위해 검색 서비스와 통합 가능 )

1-3 해결의 조건

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

3 리액티브 마이크로서비스

1-1 문제

블로킹 I/O(HTTP 기반의 RESTful JSON API와 같은) 를 사용하면 요청 처리 동안 운영체
제의 스레드를 점유 -> 운영체제의 가용 스레드가 부족해(b/c 동시 요청 수가 증가 또는 요청과 관련된 컴포넌트 증가시) 응답 시간이 늦어지거나 서버가 중단되는 문제

1-2 해결

논블로킹 I/O를 사용해 db나 다른 마이크로서비스가 처리하길 기다리는 동안 스레드가 할당되는 것을 막음

1-3 해결의 조건

  • 가능하다면 비동기 프로그래밍 모델을 사용 (메시지를 보낸 후 수신자가 메시지를 처리하길 기다리지 않는다)
  • if 동기식 -> 논블로킹 I/O를 사용 (==응답을 기다리는 동안에도 스레드 할당 없이 동기식 요청을 실행하는 리액티브 프레임워크)
  • 자가 치유 : 의존하는 서비스가 중단되더라도 응답할 수 있도록 탄력성 있게 설계

4 구성 중앙화

1-1 문제

다수의 마이크로서비스 인스턴스가 배포된 MSA 기반의 시스템 환경에서의 문제
1. 실행 중인 모든 마이크로서비스 인스턴스의 구성 정보를 한눈에 파악하는 방식 문제
2. 구성을 업데이트-> 관련된 모든 마이크로서비스 인스턴스가 올바르게 업데이트 시키는 방식 문제

1-2 해결

시스템 환경에 모든 마이크로서비스의 구성 정보를 저장하는 새 컴포넌트(==구성 서버)를 추

1-3 해결의 조건

마이크로서비스 집합에 대한 구성 정보를 한 곳에 저장하고 환경별(예: dev, test, qa, prod)
설정을 지원

5 로그 분석 중앙화

1-1 문제

  1. 각 마이크로서비스 인스턴스가 로컬에 로그 파일을 기록하는 상황-> 전체 시스템 환경에서 발생하는 사건을 개괄하는 방법?
  2. 문제가 발생한 마이크로서비스 인스턴스를 찾아서 로그 파일에 오류 메시지 작성 방법?
  3. 최종 사용자가 문제 보고시 이와 관련 로그 메시지를 찾는 방법

1-2 해결

로그를 중앙화해 관리

새 마이크로서비스 인스턴스를 감지해 로그 이벤트를 수집하고, 로그 이벤트를 해석해 구조적이고 검색 가능한 형식으로 중앙 db에 저장 하고, 그 이벤트를 조회 및 분석하기 위한 API와 그래픽 도구를 제공하는 새 컴포넌트 추가

6 분산 추적

1-1 문제

시스템 환경에 대한 외부 호출 처리하는 동안 마이크로서비스 사이의 요청 및 메시지가 추적가능 해야함

1-2 해결

관련된 모든 요청 및 메시지에 상관 ID를 넣어야 하고, 모든 로그 이벤트에 상관 ID 부여. (상관 id를 중앙화 로깅 서비스에 검색해서 로그 이벤트 서치)

1-3 해결의 조건

1 모든 수신 요청과 이벤트에 고유 상관 ID를 할당
2 마이크로서비스에서 외부로 요청이나 메시지를 보낼 때는 요청과 메시지에 상관 ID를 넣어서 보내야함
3 모든 로그 이벤트에는 사전에 정의한 형식의 상관 ID가 있어야 함

7 서킷 브레이커

1-1 문제

동기 방식으로 상호 통신하는 마이크로서비스 시스템 환경은 연쇄 장애가 발생할 여지가 있음.

1-2 해결

서킷 브레이커 추가 : 대상 서비스에 문제가 있다는 것을 감지 -> 새요청을 보내지 않도록 차단

1-3 해결의 조건

  1. 서비스에 문제 감지시 시간 초과 무시하고 바로 실패하도록 서킷 열기
  2. 장애 복구용 프로브(=반열림 서킷) 사용. == 서비스가 정상 동작하는지 확인하고자 주기적으로 요청을 보냄
  3. 프로브가 서비스의 정상 동작을 감지하면 서킷 닫음

8 제어 루프

1-1 문제

중단되거나 지연된 마이크로서비스 인스턴스를 수동으로 감지하고 대처하는 것이 어려움 (다수 서비스가 여러 서버 분산된 시스템환경에서 )

1-2 해결

제어루프를 시스템 환경에 추가 : 시스템 환경의 상태를 관찰

9 모니터링 및 경고 중앙화

1-1 문제

응답 시간이나 하드웨어 자원 사용량이 지나치게 높은 경우 문제의 근본 원인을 찾기 어려움

1-2 해결

모니터 서비스 를 시스템 환경에 추가 : 마이크로서비스 인스턴스가 사용하는 하드웨어 자원 사용량에 대한 메트릭metric을 수집

1-3 해결의 조건

  1. auto-scaling된 서버 포함해 시스템 환경에서 사용하는 모든 서버의 메트릭을 수집해야함
  2. 새로 시작된 마이크로서비스 인스턴스를 감지해 메트릭을 수집
  3. 수집한 메트릭을 조회 및 분석하기 위한 API와 그래픽 도구를 제공 필요

디자인패턴 구현 오픈소스 도구

정리

1장에서는 마이크로서비스의 필수 개념과 장점 및 문제점을 소개했다. 마이크로서비스 기반 아키텍처와 문제 해결을 위한 디자인 패턴, 소프트웨어를 을 설명했다.
(정의)마이크로서비스는 기본적으로 독자적인 업그레이드와 스케일링이 가능한 독립 소프트웨어 컴포넌트다.
(목적)빠르게 개발해 지속적으로 배포하고 수동 혹은 자동으로 쉽게 스케일링하기 위해 일체형 애플리케이션을 작은 컴포넌트로 나눈다.
(조건) 마이크로서비스를 만들기 위해서는 독립적인 컴포넌트들이 아무것도 공유하지 않는 아키텍처를 유지 하고, 명확한 인터페이스를 통해서만 통신하고, 개별적인 런타임 프로세스로 배포하고, 각 인스턴스가 stateless여야 한다.
(문제) 마이크로서비스는 동기식 통신을 사용하는 다수의 소형 컴포넌트는 연쇄 장애 유발 가능하다는 문제와, 다수의 소형 컴포넌트를 최신 상태로 유지가 어렵고 컴포넌트 수준의 하드웨어 자원 사용량 분석 어렵다는 문제와, 많은 컴포넌트가 처리에 관여하는 요청은 추적이 어렵다는 문제 등이 있다. 이러한 문제들을 완화하는 방식으로 디자인패턴을 소개하고 있다.
(디자인패턴) 클라이언트가 마이크로서비스와 그 인스턴스를 찾을 수 있어야 한다는 문제를 해결하기 위한 '서비스 검색 ', 일부 마이크로서비스만 시스템 환경 외부에 공개 + 그외는 외부 접근 못하게 숨겨야한다는 문제를 해결하기 위한 '에지 서버', 운영체제의 가용 스레드가 부족해 응답 시간이 늦어지거나 서버가 중단되는 문제를 해결하기 위한 '리액티브 마이크로서비스' , 실행 중인 모든 마이크로서비스 인스턴스의 구성 정보를 한눈에 파악하는 방식과 구성을 업데이트-> 관련된 모든 마이크로서비스 인스턴스가 올바르게 업데이트 시키는 방식의 문제를 해결하기 위한 '구성 중앙화' , 전체 시스템 환경에서 발생하는 사건을 개괄하는 방법과 문제가 발생한 마이크로서비스 인스턴스를 찾아서 로그 파일에 오류 메시지 작성 방법, 최종 사용자가 문제 보고시 이와 관련 로그 메시지를 찾는 방법의 문제를 해결하기 위한 '로그 분석 중앙화' 시스템 환경에 대한 외부 호출 처리하는 동안 마이크로서비스 사이의 요청 및 메시지가 추적가능해야한다는 문제를 해결하기 위한 '분산 추적', 동기 방식으로 상호 통신하는 마이크로서비스 시스템 환경은 연쇄 장애가 발생할 여지가 있다는 문제를 해결하는 '서킷 브레이커', 중단되거나 지연된 마이크로서비스 인스턴스를 수동으로 감지하고 대처하는 것이 어렵다는 문제를 해결하는 '제어루프' , 응답 시간이나 하드웨어 자원 사용량이 지나치게 높은 경우 문제의 근본 원인을 찾기 어렵다는 문제를 해결하는 '모니터링 및 경고 중앙화' 의 패턴을 소개한다.

profile
HelloWorld! 같은 실수를 반복하지 말기위해 적어두자..

0개의 댓글