일체형 애플리케이션을 서로 협력하는 독립 소프트웨어 컴포넌트로 나누는 것이며,
애플리케이션을 쉽게 확장하고 빠르게 개발 하기 위한 아키텍처
◇ 빠르게 개발해 지속적으로 배포할 수 있어야 한다.
◇ 수동 혹은 자동으로 쉽게 스케일링 할 수 있어야 한다.
마이크로서비스는 기본적으로 독자적인 업그레이드와 스케일링이 가능한 독립 소프트웨어 컴포넌트로서, 다음의 기준을 충족해야 한다.
◇ 아무것도 공유하지 않은 아키텍쳐 유지해야 한다.
즉, 데이터베이스의 데이터를 공유하지 않는다.
◇ 명확한 인터페이스를 통한 통신해야 한다.
동기 서비스를 사용하거나 API를 이용한 메시징 방식을 사용할 수 있는데
이때 사용하는 메세지 형식은 버전 관리 전략에 따라 안정적으로 문서화 되고 개선 돼야 한다.
◇ 개별적인 런타임 프로세스 배포해야 한다.
각 마이크로서비스 인스턴스는 도커 컨테이너와 같이 독립된 런타임 프로세스를 실행해야 한다.
◇ 마이크로서비스 인스턴스는 상태가 없다.(stateless)
따라서, 모든 마이크로 서비스 인스턴스가 마이크로서비스로 돌아오는 요청을 처리할 수 있다.
마이크로서비스는 여러개의 작은 서버에 배포할 수 있음으로 업그레이드나 교체하기가 일체형 애플리케이션보다 손쉽다.
◇ 동기적 통신을 사용하는 다수의 소형 컴포넌트는 연쇄 장애를 일으킬 수 있음
◇ 다수의 소형 컴포넌트를 최신 상태로 유지하기 어려움
◇ 많은 컴포넌트가 처리에 관여하는 요청을 추적하기 어려움(로컬에 로그 이벤트를 저장하면 근본 원인 분석을 수행하기 어려움)
◇ 컴포넌트 수준의 하드웨어 자원 사용량 분석이 어려움
◇ 다수의 소형 컴포넌트로 수동으로 구성하고 관리하는 것은 비용 크고 오류가 잦음
◇ 독립 컴포넌트 그룹으로 나누면 분산 시스템을 형성함(다루기 어려움)
◇ 시스템 환경에 항상 문제가 있다는 가정을 기반으로 마이크로서비스 아키텍처를 설계
◇ 문제를 감지하여 고장난 컴포넌트를 다시 시작할 수 있도록 하고, 고장난 마이크로서비스 인스턴트에 요청이 안가도록 함
◇ 문제가 해결되면 서비스 요청이 다시 시작되도록 함
◇ 마이크로서비스 관리는 완전히 자동화가 이루어지도록 함
디자인패턴을 사용하여 앞서 언급한 문제를 완화할 수 있다.
디자인패턴이란? 특정 상황에서 발생하는 문제에 대하 재사용 가능한 해결책을 정리한 것
◇ 문제점
∨ 컨테이너 등에서 실행되는 마이크로서비스 인스턴스는 시작하면서 동적 IP 주소를 항상 받는 것이 일반적
∨ 마이크로서비스가 노출하는 HTTP 기반의 REST API를 클라이언트에서 호출하는 것을 어렵게 함
◇ 해결책
∨ 현재 사용 가능한 마이크로서비스로 그 인스턴스를 추적하는 새 컴포넌트(서비스 검색 서비스)를 시스템 환경에 추가
◇ 해결책의 필요요건
∨ 마이크로서비스와 마이크로서비스 인스턴스의 자동 등록을 해지함
∨클라이언트는 마이크로서비스의 논리 엔드포인트에 요청을 보낼 수 있어야 함
(요청은 사용 가능한 마이크로서비스 인스턴스 중에 하나로 라우팅)
∨ 마이크로서비스에 대한 요청은 가용 인스턴스로 로드 밸런싱 되어야 함
∨요청을 라우팅 하지 않고 상태가 비정상적인 인스턴스를 감지 할 수 있어야 함
∨ 클라이언트 측 라우팅 : 클라이언트는 서비스 검색 서비스와의 통신을 지원하는 라이브러리를 사용해 요청을 보낼 인스턴스를 찾음
∨ 서버 측 라우팅
위 인프라는 모든 요청을 전달하는 리버스 프록시를 노출함. 리버스 프록시는 클라이언트를 대신해 적절한 인스턴스로 요청을 전달
◇ 문제점
∨ 마이크로서비스 시스템 환경에선 일부 마이크로서비스만 외부에 공개하고, 그 외에 마이크로서비스는 숨기는게 바람직함
∨ 공개된 마이크로서비스는 악의적인 클라이언트의 요청으로부터 보호해야 함
◇ 해결책
∨ 모든 요청이 거치는 시스템 환경에 새 컴포넌트(에지 서버)를 추가함
◇ 해결책의 필요요건
∨ 외부 요청을 허용하는 마이크로서비스로만 요청을 라우팅함
∨ 표준 프로토콜과 OAuth, OIDC, JWT, 토큰, API 키 등의 모범 사례를 활용하여 신뢰할 수 있는 클라이언트인지 확인
◇ 문제점
∨ 관례적으로 자바 개발자는 Restful JSON API와 같은 블로킹 I/O 모델 사용하여 동기식 통신을 구현해 옴
∨ 블로킹 I/O를 사용하면 요청을 처리하는 동안 운영체제의 스레드를 점유함
∨ 동시 요청수가 증가하거나 요청과 관련된 컴포넌트가 증가하면 운영체제의 가용 스테드가 부족하여 서버가 중단 될 수 있음
◇ 해결책
∨ 논블로킹 I/O를 사용해 데이터베이스나 다른 마이크로 서비스가 처리하길 기다리는 동안 스레드가 할당되지 않도록 함
◇ 해결책의 필요요건
∨ 가능하다면 비동기 프로그래밍 모델을 사용 (메시지를 보낸 후 수신자가 메시지를 처리하길 기다리지 않음)
∨ 동기식 프로그래밍 모델을 선호한다면 리액티브 프레임워크를 사용
(논블로킹I/O를 사용해 응답을 기다리는 동안에도 스레드 할당 없이 동기식 요청을 실행)
∨ 자가치유
의존하는 서비스가 중단되더라도 응답할 수 있도록 탄력성 있게 설계하고, 중단된 서비스가 재개되면 클라이언트가 서비스를 다시 사용
◇ 문제점
∨ 일반적으로 애플리케이션은 여러 환경 변수나 파일에 담긴 구성 정보와 함께 배포
(다수의 마이크로서비스 인스턴스가 배포된 마이크로서비스 아키텍처 기반의 시스템 환경에서는 문제가 발생)
∨ 실행중인 모든 마이크로서비스 인스턴스의 구성 정보를 한눈에 파악하기 어려움
∨ 구성을 업데이트하고 관련 인스턴스를 올바르게 업데이트 하기 어려움
◇ 해결책
∨ 시스템 환경에 모든 마이크로서비스의 구성 정보를 저장하는 새 컴포넌트(구성 서버)를 추가함
◇ 해결책의 필요요건
∨ 마이크로 서비스 집합에 대한 구성 정보를 한 곳에 저장하고 환경별 설정(dev, test, qa, prod)을 지원
◇ 문제점
∨ 각 마이크로서비스 인스턴스가 로컬에 로그 파일을 기록하는 상황에서 전체 시스템 환경에서 발생하는 사건을 개괄하기 어려움
∨ 문제가 발생한 인스턴스를 찾아 로그 파일에 오류 메세지를 쓰기 어려움
∨ 최종 사용자가 문제를 보고 했을 때 관련 로그 메세지를 찾기가 어려움
◇ 해결책
∨ 로그를 중앙화해 관리하고, 새 컴포넌트를 추가함
◇ 해결책의 필요요건
∨ 새 마이크로 서비스 인스턴스를 감시하여 로그 이벤트를 수집
∨ 로그 이벤를 해석해 검색 가능한 형식으로 중앙 데이터베이스에 저장
∨ 로그 이벤트를 조회하고 분석하기 위한 API와 그래픽 분석 도구를 제공
◇ 문제점
∨ 시스템 환경에 대한 외부 호출을 처리하는 동안 마이크로서비스 사이에서 흐르는 요청과 메시지를 추적하기 어려움
◇ 해결책
∨ 관련 모든 요청 및 메시지에 상관 ID를 넣고 모든 로그 이벤트에도 상관 ID가 있어야 함
∨ 중앙화 된 로깅 서비스에서 상관 ID를 검색하면 관련된 로그 이벤트를 찾을 수 있음
∨ (ex.어떤 주문 번호에 대한 문제가 발생한 경우 해당 주문 처리에 관여한 모든 서비스의 로그 메시지를 찾고 싶은 경우
고객이나 제품 주문번호와 같은 식별자가 포함된 로그 이벤트를 찾고 상관 ID를 검색하면 해당 비즈니스 식별자와 관계된
모든 로그 이벤를 추적할 수 있음)
◇ 해결책의 필요요건
∨ 모든 수신 요청과 이벤트에 고유 상관 ID를 할당(헤더와 같이 찾기 쉬운 위치에 넣음)
∨ 외부로 요청이나 메시지를 보낼 때에는 상관 ID를 꼭 기입함
∨ 모든 로그 이벤트에는 사전에 정의한 형식의 상관 ID가 있어야 함
◇ 문제점
∨ 동기 방식으로 상호 통신하는 마이크로서비스 시스템 환경은 연쇄 장애가 발생할 여지가 있음
∨ 하나의 서비스가 응답하지 않으면 클라이언트 또한 요청에 응답하지 않게 됨
∨ 시스템 환경 전체에 재귀적으로 전파되어중요한 부분까지 중단 시킬 수 있음
◇ 해결책
∨ 대상 서비스에 문제가 있음을 감지하여 새 요청을 보내지 않도록 차단하는 서킷 브레이커를 추가함
◇ 해결책의 필요요건
∨ 서비스에서 문제가 감지 되면 시간 초과를 무시하고 바로 실패하도록 서킷을 오픈함
∨ 반열심 서킷이라고 하는 장애 복구용 프로브를 사용하여 정상 동작 여부를 주기적으로 파악함
◇ 문제점
∨ 분산 시스템 환경에서 중단되거나 지연된 마이크로서비스 인스턴스를 수동으로 감지하고 대처하는 것이 어려움
◇ 해결책
∨ 시스템 환경 상태를 관찰하는 새 컴포넌트(제어 루프)를 시스템 환경에 추가함
∨ 제어 루프 컴포넌트를 통하여 운영자가 지정한 상태와 실제 상태를 지속적으로 관찰하고 일치하도록 조취를 취함
◇ 구현 참고 사항
∨ 컨테이너를 기반으로 하는 환경에서는 쿠버네티스와 같은 컨테이너 오케스트레이터로 이 패턴을 구현
◇ 문제점
∨ 응답 시간이나 하드웨어 자원 이용량이 지나치게 높은 경우 문제의 근본 원인을 찾기가 매우 어려움
◇ 해결책
∨ 마이크로서비스별 하드웨어 자원 사용량을 분석 할 수 있어야 함
∨ 하드웨어 자원 사용량에 대한 메트릭을 수집하는 새 컴포넌트(모니터 서비스)를 시스템 환경에 추가함
◇ 해결책의 필요요건
∨ 오토스케일링된 서버를 포함해 시스템 환경에서 사용하는 모든 서버 메트릭을 수집
∨ 서버에서 새로 시작된 마이크로서비스 인스턴스를 감지하여 메트릭을 수집
∨ 수집한 메트릭을 조회하고 분석하기 위한 API와 그래픽 도구를 제공해야 함
문제해결을 위한 대자인 패턴과 디자인 패턴을 구현한 오픈 소스 도구 정리 표
디자인 패턴 | 스프링 부트 | 스프링 클라우드 | 쿠버네티스 | 이스티오 |
서비스 검색 | 넷플릭스 유레카, 넷플릭스 리본 |
쿠버네티스의 kube-proxy, 서비스 리소스 |
||
에지 서버 | 스프링 클라우드, 스프링 시큐리티, OAuth |
쿠버네티스의 인그레스 컨트롤러 |
이스티오의 인그레스 게이트웨이 |
|
리액티브 마이크로서비스 |
스프링 리액터, 스프링 웹플럭스 |
|||
구성 중앙화 | 스프링 컨피그 서버 | |||
로그 분석 중앙화 | ||||
분산 추적 | 스프링 클라우드 슬루스, 집킨 |
|||
서킷 브레이커 | Resilience4j | 이상 감지 | ||
제어 루프 | 쿠버네티의 컨트롤러 매니저 |
|||
모니터링 및 경고 중앙화 |
그라파나, 프로메테우스 |
키알리, 그라파나, 프로메테우스 |
마이크로서비스를 성공적으로 구현하기 위한 관련 분야 정보
데브옵스(DevOps)는 소프트웨어의 개발(Development)과 운영(Operations)의 합성어로서, 소프트웨어 개발자와 정보기술 전문가 간의 소통, 협업 및 통합을 강조하는 개발 환경이나 문화를 말한다. 데브옵스는 소프트웨어 개발조직과 운영조직간의 상호 의존적 대응이며 조직이 소프트웨어 제품과 서비스를 빠른 시간에 개발 및 배포하는 것을 목적으로 한다.
빠른 전달 위하여 개발과 운영 조직이 긴밀하게 협력하여 마이크로서비스의 전체 수명 주기를 전적으로 책임지는 팀을 구성해야함
다양한 배포 환경에서 마이크로서비스를 빌드하고, 테스트, 패키징, 배포하는 전달 체인 자동화가 필수임
이것을 파이프 라인이라고 함
"소프트웨어 구조는 그 소프트웨어를 개발한 조직의 의사소통 구조를 반영한다."
-멜빈 콘웨이, 1967
개별 마이크로서비스나 관련된 마이크로서비스 집합을 한 팀에서 맡도록 조직을 정비해야함
각 팀은 비즈니스 로직을 위한 언어나 프레임워크, 데이터베이스 기술 등을 보유해야 함
가장 어렵고 비용이 많이 드는 방식은 일체형 애플리케이션을 공조 마이크로서비스 집합으로 나누는 것.
적절한 경계를 찾아 서비스를 나누기 위하여 도메인 주도로 설계하고, 경계가 있는 콘텍스를 적용해야 함
경계가 있는 콘텍스트란? 특정 모델을 정의하고 적용할 수 있는 경계를 명시한 것
외부에서 마이크로서비스에 접근하는 공통 API를 공개하는 경우 쉽게 이해할 수 있도록 설계함
◇ 이름과 데이터 유형에 대한 설명이 일치해야함
◇ API를 변경할 때는 통제된 방식을 사용
◇ 시멘틱 버전과 같은 적절한 버전 관리 스키마를 적용
◇ 클라이언트가 여유있게 마이크레이션 할 수 있도록 여러 버전의 주요 API를 일정 기간동안 제공
◇ 마이크로서비스의 정의 : 명확한 요구 사항이 있는 일종의 독립된 분산 컴포넌트
◇ 마이크로서비스의 기반 아키텍처의 장점과 문제점
◇ 도출된 문제를 해결하기 위한 디자인패턴을 정의하고 오픈 소스 제품을 기능과 간략하게 매핑하여 표로 정리
03장 공조 마이크로서비스 집합 생성 (0) | 2021.04.07 |
---|---|
02장 스프링 부트 소개 (0) | 2021.03.17 |
댓글 영역