Cloud

[클라우드 컴퓨팅] 2. 마이크로서비스 개요

hyomee2 2025. 3. 18. 02:30

마이크로서비스란?

: 개별적으로 배포 일정을 갖고 업데이트 운영이 가능한 작고 독립적인 소프트웨어 프로세스

  • 다른 마이크로서비스와 별개로 업데이트 가능
  • 필요에 따라 외부에 노출하거나 외부 접근 불허
  • 하나의 마이크로서비스가 많은 기능을 갖지 않는다.

 


마이크로서비스 앱이란?

: 프로젝트의 주요 기능들을 수행하기 위해 서로 협업하는 작은 서비스들로 구성된 분산 프로그램

  • 클러스터 안에서 동작하는 여러 개의 작고 독립적인 서비스로 구성 (각각의 서비스나 구성 요소는 논리적 또는 가상으로 구분된 컴퓨터에 위치)


모놀리스와 마이크로서비스

1. 모놀리스

: 전체적인 앱이 단일 프로세스로 동작

  • 앱 개발 난이도가 낮다.
  • 작은 규모(= 낮은 복잡도)의 실험적 모델 개발에 적합 (작은 규모의 개발엔 microservice architecture을 적용할 필요가 없다.)
  • 시간이 지남에 따라 관리가 어려워진다.
  • 코드 변경이 어렵다.
  • 실험적 기능 추가가 어렵다.
  • 스파게티 코드가 될 수 있다.

2. 마이크로서비스

(1) 마이크로서비스가 대세가 된 이유

: 분산 애플리케이션에 대한 접근성 변화

  • 분산 애플리케이션은 매우 복잡하고 구현에 많은 비용 발생
  • 클라우드와 가상화, 가상 인프라 관리 자동화 도구(.ex. 쿠버네티스)의 등장에 따른 분산 시스템의 구축 비용 감소
    • `분산 애플리케이션 기반의 모놀리스 앱을 대체하기 위한 비용이 줄어들었다. 
    • 분산 시스템의 구성 요소들을 가능한 작게 만든 것이 마이크로서비스이다.

(2) 마이크로서비스의 장점

1) 세밀한 확장성

  • 애플리케이션의 확장성을 세밀하게 조절 가능
  • 각 서비스가 필요에 따라 독립적으로 확장 가능

2) 배포 위험 감소

  • 새로운 코드를 배포할 때의 위험을 최소화
  • 하나의 업데이트가 전체 시스템에 영향을 미치지 않음

3) 기술적 유연성

  • 개발자들이 하나의 기술 스택에 구속되지 않고, 각 서비스에 가장 적합한 기술 스택을 선택할 수 있다.

(2) 마이크로서비스의 단점

  • 어렵고 복잡하다.

(3) 마이크로서비스 최신 도구

1) 도커

  • 패키지를 만들거나 서비스 배포

2) 도커 컴포즈

  • 개발 환경에서 마이크로서비스 앱 테스트

3) 쿠버네티스

  • 클라우드에 앱을 호스트 (클라우드에 앱을 돌리고 싶을 때)

마이크로서비스 앱의 설계

1. 마이크로서비스 앱의 설계 규칙

  • 미래에 필요한 검증을 위해 지나치게 미리 설계하지 말자. (단순한 설계부터 시작)
  • 최대한 단순하게 유지하기 위해 개발 과정에 지속적인 리팩토링을 적용하자.
  • 좋은 설계가 자연스럽게 완성되도록 하자.
    • 마이크로서비스들로 구성된 커다란 앱을 미리 단정적으로 설계할 수 없다.

2. 마이크로서비스의 원칙

(1) 단일 책임 원칙

  • 하나의 (마이크로)서비스는 개념적으로 하나의 업무를 책임져야 한다.

(2) 느슨한 연결

  • 서비스 간 연결을 최소화하고, 반드시 필요한 정보가 아니면 공유하지 않는다.
  • 서비스들 간의 연결과 종속성을 최소화하면 앱에서 어떤 문제가 확산되는 일 없이 개별 서비스를 업그레이드하기 쉬워진다.      -> 변화하는 업무 요구에 맞춰 유연하게 대응 가능

(3) 강한 응집력

  • 하나의 마이크로서비스 안에서는 코드가 서로 기능적으로 연계돼 있고, 맡은 서비스 영역에 대한 문제를 풀 수 있도록 동작해야 한다.
    • 하나의 마이크로서비스가 2개 이상의 문제를 해결하거나, 책임지는 범위가 위의 경우보다 크다면 강한 응집력을 갖지 못한 것이다.

3. 도메인 기반 설계 (Domain Driven Design)

: 비즈니스 도메인을 중심으로 설계해나가는 방법

  • DDD에서 의미적 구분의 개념은 마이크로서비스의 경계를 정하는데 적합하다.

  • 마이크로서비스 분야에서는 반복되는 코드에 대해 관대하다.

개발 프로세스 확장

1. 작은 규모의 마이크로서비스 앱을 소규모로 개발하는 경우

  • 개발자들은 개발 워크스테이션에서 하나의 코드 베이스로 코드 작성과 테스트를 한다.
  • 개발자들은 호스팅된 코드 레포지토리에 코드 변경사항을 푸시해서 앱을 운영 환경에 배포하기 위한 CD 파이프라인을 트리거한다.
  • 새로운 앱을 개발할 때 빠르게 시작하는데 적합하다.

  • 하지만 규모가 커질수록 문제가 발생한다.
    • 운영 환경과 비슷한 테스트 환경 필요 (완벽하지 않은 변경 사항이 고객에게 영향을 주지 않도록)
    • 개발자 간의 간섭
      • 하나의 코드 베이스로 작업하므로 merge conflict 및 빌드 관리 실패 발생
    • 확장성 부족
      • 하나의 코드 레포지토리와 CD 파이프라인은 확장성이 없다.
    • 따라서 아래와 같이 여러 팀으로 쪼개는 방법을 생각할 수 있다.

2. 여러 팀으로 개발하는 경우

  • 각각의 팀이 다른 마이크로서비스 집합을 서로 겹치지 않게 책임을 지도록 앱을 분할한다.
  • 각 팀은 하나 이상의 마이크로서비스를 소유한다.
    • 코딩부터 테스트를 거쳐 운영 환경까지 모두 책임(가용성, 성능 유지까지)

  • 아래와 같이 마이크로서비스를 독립적으로 동작하도록 분리할 수 있다.

3. 독립적인 마이크로서비스

(1) 단일 레포지토리와 CD 파이프라인

  • 쉽게 시작할 수 있고, 인프라를 만들고 운영하는데 시간이 훨씬 적게 소비된다.
  • 단일 CD 파이프라인은 모든 마이크로서비스를 같은 속도로 출시해야 하는 문제가 있다.
    • 배포할 때마다 전체 앱이 망가질 수 있다.
    • 따라서 아래와 같이 레포지토리와 CD 파이프라인을 나눌 수 있다.

(2) 분리된 코드 레포지토리와 여러 CD 파이프라인

  • 세밀하게 배포 제어가 가능하다.
  • 전체 앱의 관리는 더 복잡해진다.

4. 코드 레포지토리의 분리

  • 마이크로서비스마다 구분되도록 레포지토리 구성
  • 새로운 레포지토리는 하나의 마이크로서비스 코드와 그 코드를 운영 환경에 배포하는 코드를 포함한다.

5. CD 파이프라인 분리

  • 마이크로서비스마다 구분된 배포 파이프라인이 필요하다.
    • 하나의 마이크로서비스 배포 파이프라인을 만든 후 재사용 가능

6. 메타리포

: 분리된 레포지토리들을 하나의 코드 레포지토리로 묶어주는 가상 코드 레포지토리

  • 단일 코드 레포지토리의 단순함과 편리함
  • 분리된 레포지토리의 독립성 유지
  • ".meta" 설정 파일을 만들어 구성
    • infrastructure는 어떤 레포지토리랑 연결돼 있고, azure-storage는 어떤 레포지토리랑 연결돼 있고....

7. 다중 환경 만들기

  • 개발자가 각자 개발 워크스테이션에서 하는 테스트로는 한계가 있다.
    • 고객이 사용 중인 운영 환경은 아니지만, 운영에 가까운 환경에서 테스트 필요

8. 운영 워크플로

  • 코드 레포지토리 안에서 배포 환경에 맞게 브랜치로 구분해서 사용
    • development branch
    • test branch
    • production branch

성능 확장성

1. 더 많은 부하를 처리하기 위한 성능 확장

  • 마이크로서비스는 성능에 대한 섬세한 제어가 가능하다.
    • 성능이 떨어지는 부분, 사용량이 최대일 때 과부하가 걸린 위치 등을 모니터링하기 쉽다.
  • 수직 확장(scale-up)만 가능한 모놀리스와는 다르게, 마이크로서비스에선 다양한 방식으로 성능 조정이 가능하다.
    • 전체 클러스터의 수직 확장
    • 전체 클러스터의 수평 확장
    • 개별 마이크로서비스의 수평 확장
    • 전체 클러스터의 탄력적인 확장
    • 개별 마이크로서비스의 탄력적인 확장
    • 데이터베이스 확장

(1) 전체 클러스터의 수직 확장 (scale-up)

  • 앱이 커지면서 클러스터가 앱을 실행하는 데 충분한 연산 능력(CPU), 메모리, 저장소 등을 보유하지 못할 수 있음                   -> 클러스터에 가용한 자원을 증가시켜야 한다.  (virtual machine의 core, 메모리, 저장소 성능 높여야 한다.)

(2) 전체 클러스터의 수평 확장 (scale-out)

: 같은 크기로 개수를 늘리는 방식

  • 일반적으로 수직 확장보다 비용이 덜 소요된다.
    • 적은 수의 크고 비싼 VM > 많은 수의 작고 싼 VM

(3) 개별 마이크로서비스의 수평 확장

  • 클러스터의 규모는 충분하지만 개별 마이크로서비스에 부하가 걸리는 경우, 부하를 여러 인스턴스로 분해할 수 있도록 수평 확장

(4) 전체 클러스터의 탄력적인 확장

  • 요청 수준에 맞게 자동으로, 그리고 동적으로 클러스터를 확장
    • 요청이 적을 때는 자동으로 필요없는 자워 해제
    • 요청 많을 때는 새로운 자원을 증가한 부하에 맞게 할당

(5) 개별 마이크로서비스의 탄력적인 확장

  • 마이크로서비스의 복제 수를 마이크로서비스 부하에 맞게 동적으로 확장하거나 줄인다.

(6) 데이터베이스 확장

  • 하나의 마이크로서비스는 자신만의 데이터베이스 하나를 가져야 한다.
    • 여기서 데이터베이스 != 데이터베이스서버
  • 그렇지 않을 경우, 공유 데이터베이스로 인해 마이크로서비스가 더 이상 독립적이지 않게 되고, 심각한 병목이 발생할 수 있다.

  • 앱이 커지면 규모가 큰 데이터베이스는 여러 독립적인 데이터베이스 서버로 분리해서 확장할 수 있다.

  • 하나의 데이터베이스를 하나의 데이터베이스 서버로 감당하기 어려워지면 샤딩(sharding, DB에 데이터를 나눠서 저장하는 것)을 이용할 수 있다.

(7) 인프라 변경 관리

  • 블루-그린 배포
    • 두 개의 운영환경을 통해 잠재적인 위험을 가진 인프라 변경으로부터 고객을 보호


모놀리스를 마이크로서비스로 전환하기

1. 마이크로서비스 플랫폼 구성

  • 쿠버네티스 클러스터 생성

2. 자연스러운 경계(DDD)로 분할하기 

  • 모놀리스가 거대하고 복잡하다면 리팩토링이 필요하다.

3. 가장 자주 변경하는 부분을 추출

  • 마이크로서비스가 주는 장점을 바로 누릴 수 있다.

4. 과정 반복


* 본 게시물은 성신여자대학교 박지웅 교수님의 '클라우드컴퓨팅' 강의 내용을 토대로 작성했습니다.

'Cloud' 카테고리의 다른 글

[클라우드 컴퓨팅] 1. 클라우드 컴퓨팅 개요  (0) 2025.03.10