/spring-microservice-kotlin

Spring Microservices Book Learn with Kotlin

Primary LanguageKotlinMIT LicenseMIT

스프링 마이크로서비스 코딩 공작소

도서 및 Github 코드 를 참조하여 Kotlin으로 프로젝트를 실습하고, 각 chapter 별로 내용을 정리합니다.

목차

환경 및 설정

환결 설정

  • OpenJDK: 21.0.4(21.0.4-amzn Corretto)

도구

  • Tool: IntelliJ Community 2024.02

API 테스트

  • API: 모든 API는 Postman을 이용하여 테스트를 진행했습니다. 해당 import 파일 을 이용하여 API 동작 확인을 할 수 있습니다.

docs 폴더의 Book Spring Microservice API.postman_collection.json 파일을 Postman에 import를 하여 API 테스트를 하면 쉽게 할 수 있습니다.

코드 실습

기본적인 API 동작을 확인할 수 있습니다. 스프링 Boot를 이용하여 REST API 호출부를 실습합니다.

도서 챕터별 정리

1장 스프링, 클라우드와 만나다

요약: 모놀리스 아키텍처와 마이크로서비스 아키텍처에 대한 개념 이해 및 다양한 패턴 학습

내용 정리(펼치기)

1.1 마이크로서비스 아키텍처로 진화

  1. 모놀리스 아키텍쳐

    • 장점
      • 모든 UI, 비즈니스 및 데이터베이스 액세스 로직이 하나로 배포
      • 관리가 쉬움
      • 구축 및 배포가 쉬움
      • 변경 가능성이 낮은 경우 모놀리스로 시작하는게 좋음
    • 단점
      • 규모가 커지면 관리가 어려움
  2. 마이크로서비스 아키텍쳐

    • 장점
      • 각 구성 요소는 작은 책임 영역을 담당하고 서로 독립적 배포
      • 잘 분해하고 분리하면 대규모 코드베이스에서 발생하는 전통적인 복잡성 문제를 해결하는데 도움이 됨
    • 단점
      • 잘 분해라고 분리하기가 어려움
      • 여러 저장소로 나누어지기 때문에 개인이 관리하기 힘듬(12 저장소 관리..)
      • CCOP(Complex, Consistency, Operation overhead, Performance) 문제점

1.4 이 책의 내용

  • 마이크로서비스의 정의, 모범 사례 및 마이크로서비스 기반 구축을 위한 설계 고려 사항
  • 마이크로서비스 기반 애플리케이션을 구축하면 안되는 경우(중요..)
  • 도커의 정의 및 마이크로서비스 기반 애플리케이션 통합 방법
  • 애플리케이션 지표를 만들고 모니터링 도구로 시각화 방법
  • ELK 스택으로 애플리케이션 로그 관리 방법
  • 배운 내용 활용하여 배포 파이프라인 구축 방법(CI/CD?)

1.5 클라우드 및 마이크로서비스 기반 애플리케이션

실습코드 참조 코드

  1. 클라우드 컴퓨팅에서는 여러 가지 서비스 모델

    1. IaaS (Infrastructure as a Service)

      • 설명: IaaS는 인프라를 서비스로 제공하는 모델로, 사용자에게 서버, 스토리지, 네트워크 등의 가상화된 자원을 제공. 사용자는 인프라의 운영 체제, 네트워크 설정 등을 직접 관리하지만, 물리적인 하드웨어는 클라우드 제공자가 관리
      • 예시: Amazon Web Services (AWS) EC2, Microsoft Azure, Google Cloud Platform (GCP)
      • 특징: 유연성과 확장성이 뛰어나며, 자원을 필요에 따라 쉽게 추가하거나 제거할 수 있음
    2. SaaS (Software as a Service)

      • 설명: SaaS는 소프트웨어를 인터넷을 통해 제공하는 서비스 모델로, 사용자는 설치나 유지보수 없이 웹 브라우저나 애플리케이션을 통해 소프트웨어를 사용할 수 있음. 애플리케이션의 모든 관리와 업데이트는 서비스 제공자가 수행
      • 예시: Google Workspace (Gmail, Google Docs), Salesforce, Microsoft 365
      • 특징: 사용자가 소프트웨어를 직접 설치하거나 관리할 필요가 없고, 언제 어디서나 인터넷 연결만 있으면 접근 가능
    3. PaaS (Platform as a Service)

      • 설명: PaaS는 개발자들이 애플리케이션을 개발하고 배포할 수 있는 플랫폼을 제공. 이 플랫폼은 운영 체제, 미들웨어, 데이터베이스 관리 시스템 등을 포함하며, 개발자가 인프라 관리 없이 애플리케이션 개발에 집중할 수 있음
      • 예시: Google App Engine, Microsoft Azure App Service, Heroku
      • 특징: 개발 환경을 빠르게 설정하고 관리할 수 있어 개발 시간을 단축하고, 복잡한 인프라 운영을 클라우드 제공자가 처리
    4. CaaS (Container as a Service)

      • 설명: CaaS는 컨테이너화된 애플리케이션을 배포하고 관리할 수 있는 환경을 제공. Docker와 Kubernetes와 같은 컨테이너 오케스트레이션 도구를 사용하여 애플리케이션을 쉽게 배포하고 확장할 수 있음
      • 예시: Amazon ECS, Google Kubernetes Engine (GKE), Microsoft Azure Kubernetes Service (AKS)
      • 특징: 컨테이너 기반 애플리케이션의 빠른 배포와 확장성이 용이하며, DevOps 환경에서 특히 유용
    5. FaaS (Function as a Service)

      • 예시: AWS Lambda, Google Cloud Functions, Azure Functions.
      • 설명: FaaS는 이벤트 기반으로 특정 기능(코드)을 실행할 수 있는 서버리스 컴퓨팅 모델. 사용자는 코드를 작성하고 업로드하면, 서비스 제공자가 이를 실행하고 필요할 때만 비용이 발생. 인프라와 서버 관리를 하지 않아도 되며, 트리거 기반으로 애플리케이션이 작동
      • 특징: 서버리스 환경으로, 특정 이벤트에 반응하여 실행되며, 애플리케이션 규모가 유동적일 때 유리
    6. DaaS (Desktop as a Service)

      • 설명: DaaS는 가상 데스크탑 환경을 클라우드에서 제공하는 서비스. 사용자는 클라우드 상에서 가상 데스크탑에 접속하여 업무를 수행할 수 있으며, 데스크탑의 운영 체제 및 애플리케이션도 클라우드에서 관리
      • 예시: Amazon WorkSpaces, VMware Horizon Cloud
      • 특징: 물리적인 PC 없이도 언제 어디서나 데스크탑 환경에 접근할 수 있으며, 보안 관리 및 업데이트가 중앙에서 이루어짐

1.6 마이크로서비스는 코드 작성 이상을 의미한다.

견고한 서비스를 작성하려면 아래와 같이 여러 가지 주제를 고려해야 함

  • 적정 규모: 서비스가 한 가지 책임 영역에 집중되도록 하려면 어떻게 해야 하는가?
  • 마이크로서비스가 너무 많은 책임을 지지 않도록 적절한 마이크로서비스 크기를 유지하는 방법
  • 위치 투명성: 서비스 호출에 대한 물리적 상세 정보를 관리하는 방법. 마이크로서비스 애플리케이션에서 다수의 서비스 인스턴스가 빠르게 시작하고 종료
  • 회복성: 실패한 서비스를 우회하고 빠른 실패 방식을 적용하여 마이크로서비스 소비자와 애플리케이션의 전반적인 무결성을 보호하는 방법
  • 반복성: 서비스의 모든 새 인스턴스가 시작할 떄 운영 환경의 다른 서비스와 동일한 구성과 코드베이스를 보장하는 방법
  • 확장성: 서비스 간 직접적인 종속 관계를 최소화하고 마이크로서비스를 적절히 확장할 수 있도록 통신 방식을 구축하는 방법
  • 핵심 마이크로서비스 개발, 라우팅, 클라이언트 탄력성, 보안, 로깅 및 추적, 애플리케이션 지표, 빌드 및 배포 패턴

1.7 핵심 마이크로서비스 개발 패턴

  • 서비스 세분성: 서비스를 서로 다른 비즈니스 문제 도메인의 책임과 중첩될 정도로 지나치게 크게 나누면 시간이 지나 유지 관리하고 변경하기 어려움
  • 통신 프로토콜: 동기 프로토콜의 경우 HTTP 기반 REST가 일반적인 통신이며, 비동기 프로토콜의 경우 아파치 카프카, RabbitMQ, AMQP 등을 사용
  • 인터페이스 설계: 서비스 인터페이스 설계 및 서비스를 어떻게 구조화 하는게 좋을 지(2장에서 다룰 예정)
  • 서비스 구성 관리: 클라우드에 있는 서로 다른 환경 간 마이크로서비스의 구성을 호환하려면 어떻게 구성 관리 해야하는지 (5장에서 다룰 예정)
  • 서비스 간 이벤트 처리: 서비스간 의존성을 최소화하고 애플리케이션의 탄력성을 높이고자 이벤틀르 사용하여 서비스를 분리하는 방법은 어떻게 하는지(10장에서 다룰 예정(스프링 클라우드 스트림))

1.8 마이크로서비스 라우팅 패턴

마이크로서비스 라우팅 패턴은 마이크로서비스를 사용하려는 클라이언트 애플리케이션이 서비스 위치를 발견하고 서비스로 라우팅하는 방법에 관한 방법

  • 서비스 디스커버리: 6장에서 자세히 다룰 예정이며, 서비스 디스커버리는 클라이언트 대응 서비스가 아니라 내부 서비스임을 기억하는게 좋음
  • 서비스 라우팅: API 게이트웨이를 사용하면 모든 서비스에 대한 단일 진입점을 제공하여 마이크로서비스 애플리케이션의 여러 서비스와 서비스 인스턴스에 대해 일관된 보안 정책과 라우팅 규칙을 적용할 수 있음(8장에서 자세히 다룰 예정)

1.9 마이크로서비스 클라이언트 회복성

서비스 문제 발생 시 연쇄적으로 서비스 소비자까지 전파되는 것을 막는 것이 중요합니다. 이와 관련된 4가지의 클라이언트 회복성 패턴

  • 클라이언트 부하 분산: 여러 인스턴스에 대한 호출이 정상 인스턴스에 분산되도록 서비스 인스턴스 위치를 캐싱하는 방법
  • 회로 차단기 패턴: 문제가 있는 서비스 호출하지 않는 방법
  • 폴백 패턴: 마이크로서비스 호출 실패 시 다른 서비스 클라이언트가 작업을 수행하도록 플러그인 메커니즘을 제공하는 방법
  • 벌크헤드 패턴: 한 서비스의 오작동 호출이 애플리케이션의 다른 곳에 나쁜 영향을 미치지 않도록 호출을 격리하는 방법

1.10 마이크로서비스 보안 패턴

적절한 자격 증명을 가진 승인된 요청만 서비스를 호출할 수 있도록 할 수 있는 3가지의 보안 패턴 방법

  • 인증: 서비스를 호출하는 서비스 클라이언트가 누구인지 확인하는 방법
  • 인가(권한 부여): 서비스 클라이언트가 수행하려는 행동에 대한 수행 자격 여부를 확인하는 방법
  • 자격 증명 관리와 전파: OAuth2와 JWT 같은 토큰 기반의 보안 표준 사용 방법

1.11 마이크로서비스 로깅과 추적 패턴

마이크로서비스 아키텍처의 단점은 간단한 동작 하나에 수많은 마이크로서비스 호출이 발생하여 문제를 디버깅하고 추적 및 모니터링하기가 매우 어려움
이를 해결하기 위해 분산 추적을 달성하는 세 가지 핵심 로깅 및 추적 패턴

  • 로그 상관관계: 한 트랜잭션에 대해 여러 서비스에서 생서된 모든 로그를 함께 연결하는 상관관계 ID(correlation ID)를 구현하는 방법
  • 로그 수집: 마이크로서비스가 출력한 모든 로그를 수집하여 확인하는 방법
  • 마이크로서비스 추적: 트랜잭션과 관련된 모든 서비스 간 클라이언트 트랜잭션 흐름을 시각화하고 성능 특성을 살펴보는 방법

1.12 애플리케이션 지표 패턴

애플리케이션 지표 패턴은 애플리케이션이 지표를 모니터링 하는 방법과 애플리케이션의 가능한 실패 원인을 경고하는 방법

해당 패턴은 서비스의 잠재적인 성능 문제를 방지하고자 지표 서비스가 비즈니스와 연관된 데이터를 수집, 저장, 질의하는 방법을 보여줌

  • 지표: 애플리케이션 상태에 대해 중요한 정보를 생성하고 이 정보의 지표를 노출하는 방법
  • 지표 서비스: 애플리케이션 지표를 저장하고 질의하는 곳
  • 지표 시각화 제품군: 애플리케이션과 인프라스트럭처에 대해 비즈니스와 연관된 시계열 데이터를 시각화

지표 모니터링은 마이크로서비스 아키텍처에 필수적이며, 마이크로서비스의 높은 분산성으로 인해 모놀리식 구조보다 더 높은 경향이 있음(복잡하고 어렵다?)

1.13 마이크로서비스 빌드/배포 패턴

마이크로서비스 아키텍처의 핵심 부분 중 하나는 한 마이크로서비스의 각 인스턴스가 모두 동일해야 함

서버가 배포된 후 서버의 변경 사항으로 발생되는 구성 불일치는 애플리케이션의 안정성을 해칠 수 있어 발생을 막아야 함

빌드 및 배포 파이프라인을 구축하는 방법

  • 빌드 및 배포 파이프라인: 조직의 모든 환경에서 원 버튼 클릭 빌드와 배포를 중시하는 반복적인 빌드 및 배포 프로세스를 구축하는 방법
  • 코드형 인프라스트럭처: 소스 제어로 실행되고 관리되는 서비스 프로비저닝 처리 방법
  • 불변 서버: 마이크로서비스 이미지가 생성되고 배포된 후 절대 변경되지 않도록 하는 방법
  • 피닉스 서버: 개별 컨테이너를 실행하는 서버가 정기적으로 분해되어 불변 이미지로 재생성되도록 하는 방법

2장 스프링 클라우드와 함께 마이크로서비스 세계 탐험

요약: [추후 작성]

내용 정리(펼치기)

2.1 스프링 클라우드란?

스프링 클라우드(Spring Cloud)는 마이크로서비스 아키텍처(Microservices Architecture)를 쉽게 구현하고 관리할 수 있도록 돕는 스프링 프레임워크의 확장 모듈

마이크로서비스는 애플리케이션을 여러 독립적인 서비스로 분리하는 방식인데, 이 방식에서는 각각의 서비스가 개별적으로 배포되고 유지보수

스프링 클라우드는 이러한 분산 시스템에서 공통적으로 발생하는 문제들을 해결하는 다양한 도구와 라이브러리를 제공

주요 기능

  • 서비스 디스커버리: 분산된 여러 서비스들이 서로를 찾고 통신할 수 있도록 도와주며, Eureka 같은 서비스가 대표적
  • 분산형 구성 관리: 여러 서비스에서 공통으로 사용하는 설정 값을 중앙에서 관리하고 배포할 수 있으며, Spring Cloud Config를 통해 이를 구현할 수 있음
  • 로드 밸런싱: 서비스 간 요청을 분산시키는 로드 밸런싱 기능을 제공 하며, Ribbon이나 Spring Cloud LoadBalancer 같은 도구가 사용
  • API Gateway: 모든 마이크로서비스를 하나의 진입점(API Gateway)에서 관리하고, 각 서비스에 대한 라우팅 및 보안 정책을 정의할 수 있으며, Zuul이나 Spring Cloud Gateway가 이를 처리
  • 분산 추적: 서비스 간의 호출 및 상태를 추적 및 스프링 클라우드 슬루스(Spring Cloud Sleuth)를 통해 분산된 로깅과 트레이싱을 제공하며, ELK 스택 등 로깅 집계 기술 도구와 집킨 등 추적 도구와 결합될 때 더 효용성이 있음
  • 서킷 브레이커: 마이크로서비스 간의 의존성 문제가 발생할 때, 시스템 전체가 중단되는 것을 방지하는 서킷 브레이커 패턴을 지원하며, 이를 통해 문제가 있는 서비스에 대한 호출을 빠르게 중단하고, 시스템의 안정성을 유지할 수 있습니다. Hystrix와 같은 도구가 사용

주요 컴포넌트

  • Spring Cloud Netflix: 넷플릭스가 만든 마이크로서비스 도구 모음을 포함하며, Eureka, Hystrix, Ribbon 등의 도구들이 포함
  • Spring Cloud Gateway: 경량화된 API 게이트웨이 역할을 하며, 요청 라우팅, 보안, 필터링 등의 기능을 제공
  • Spring Cloud Config: 중앙화된 설정 관리 시스템을 제공

장점

  • 확장성: 애플리케이션을 독립적인 서비스로 나누어 개발, 배포 및 확장이 용이
  • 유연성: 다양한 클라우드 서비스나 인프라와 쉽게 연동 가능
  • 관찰 가능성(Observability): 분산된 서비스들을 추적하고 모니터링하기 위한 다양한 툴을 제공해 서비스 상태를 쉽게 파악할 수 있음

2.2 스프링 클라우드 예제 소개

실제로 예제 실습은 하지 않지만, @EnableEurekaClient 애너테이션에 대한 기능을 설명함

@EnableEurekaClient는 Spring Cloud Netflix 프로젝트의 어노테이션 중 하나로, Spring Boot 애플리케이션을 Eureka 클라이언트로 등록하기 위해 사용

이를 통해 애플리케이션이 Eureka 서버에 자신의 정보를 등록하고, 다른 서비스들이 Eureka 서버를 통해 이 애플리케이션을 찾을 수 있음

주요 기능

  • 서비스 등록: @EnableEurekaClient는 애플리케이션이 시작될 때 자동으로 Eureka 서버에 자신을 등록하며, 이렇게 등록된 애플리케이션은 다른 마이크로서비스들이 해당 애플리케이션의 위치(IP, 포트 등)를 찾을 수 있도록 Eureka 서버에 정보가 저장
  • 서비스 디스커버리: Eureka 클라이언트는 다른 마이크로서비스들의 정보를 조회할 수 있으며, 이를 통해 서로 위치를 몰라도 네트워크 상에서 서비스 간의 통신이 가능
  • 부하 분산: 여러 인스턴스가 같은 서비스를 제공할 때, Eureka 클라이언트는 부하를 분산하여 처리할 수 있습니다. Eureka 서버에서 여러 인스턴스 중 하나를 선택하여 호출

2.3 클라우드 네이티브 마이크로서비스 구축 방법

클라우드 네이티브: 클라우드 네이티브 애플리케이션은 클라우드 컴퓨팅 아키텍처의 모든 이점과 서비스를 활용할 수 있도록 특별히 설계됨

클라우드 네이티브 개발을 위한 네 가지 원칙

  • 데브옵스는 개발과 운영의 약어로 개발자와 IT 운영 간 커뮤니케이션과 협업, 통합에 중점을 둔 소프트웨어 개발 방법론을 의미
  • 마이크로서비스는 작고, 느근하게 결합된 분산 서비스
  • 지속적 전달(CD(continuous delivery))은 소프트웨어 개발 관행
  • 컨테이너는 가상 머신 이미지에 마이크로서비스를 배포하는 자연스러운 확장

12-Factor 애플리케이션은 현대 클라우드 네이티브 애플리케이션을 설계할 때 따를 수 있는 12가지의 모범 사례를 정의한 방법론

이는 확장성, 유지보수성, 이식성을 높이기 위해 만들어졌으며, 특히 마이크로서비스나 클라우드 환경에서 많이 사용되며

12 팩터 애플리케이션의 모범 사례 정보

1. 코드베이스 (Codebase)
여러 배포를 포함한 하나의 코드베이스: 모든 애플리케이션은 하나의 코드베이스에 의존하고, 그 코드베이스는 여러 환경(예: 개발, 테스트, 프로덕션)에서 배포될 수 있으며, 여러 애플리케이션이 동일한 코드를 공유하거나, 단일 코드베이스에서 다수의 앱이 나오는 상황은 피해야 함

2. 종속성 관리 (Dependencies)
명시적 선언과 격리: 외부 라이브러리나 패키지 등 모든 종속성은 package manager 등을 통해 명시적으로 선언해야 하며, 시스템에 의존하지 않고 애플리케이션 자체에 포함되도록 격리

3. 설정 (Config)
설정과 코드의 분리: 애플리케이션의 설정 값(예: 데이터베이스 URL, API 키 등)은 코드와 분리되어 환경 변수로 관리되어야 하며, 배포 환경에 맞춰 쉽게 변경될 수 있어야 함

4. 백엔드 서비스 (Backing Services)
백엔드 서비스는 외부 리소스로 취급: 데이터베이스, 메시지 큐, 캐시 서버 등은 외부 서비스로 간주하며, 쉽게 교체 가능해야 하며, 설정을 통해 서비스 위치를 정의하고, 내부에 종속되지 않게 설계 필요

5. 빌드, 릴리스, 실행 (Build, Release, Run)
빌드, 릴리스, 실행을 분리: 애플리케이션의 빌드, 릴리스, 실행 과정을 각각 분리
빌드는 소스 코드를 컴파일하고 패키징하며, 릴리스는 빌드된 파일을 설정과 함께 결합하여 실행할 수 있는 단위로 만들어야 함

6. 프로세스 (Processes)
무상태 프로세스로 설계: 애플리케이션은 무상태(stateless)로 설계되어야 하며, 모든 상태는 데이터베이스나 외부 저장소에 저장해야 하며, 프로세스는 언제든지 시작되고 중단될 수 있어야 됨

7. 포트 바인딩 (Port Binding)
포트를 바인딩해 서비스 제공: 애플리케이션은 웹 서버와 같은 외부 도구 없이 자체적으로 포트를 통해 서비스를 제공해야 하며, 애플리케이션 자체가 웹 서버 역할을 하도록 설계

8. 동시성 (Concurrency)
프로세스 모델을 통한 확장: 애플리케이션은 여러 프로세스로 수평 확장이 가능해야 하며, 프로세스는 독립적으로 실행되어야 함

9. 폐기 가능성 (Disposability)
빠르게 시작하고, 안전하게 종료: 애플리케이션의 프로세스는 빠르게 시작하고, 신속하고 안전하게 종료될 수 있어야 하며, 갑작스러운 종료도 대비해야 하며, 이는 시스템의 유연성을 높입니다.

10. 개발/프로덕션 일치 (Dev/Prod Parity)
개발, 테스트, 프로덕션 환경을 최대한 유사하게 유지: 개발 환경과 프로덕션 환경의 차이를 최소화하여 배포 전후의 문제를 방지해야 하며, 이를 통해 개발 시 발견하지 못한 문제를 프로덕션에서 발견하는 일을 줄일 수 있음

11. 로그 (Logs)
이벤트 스트림으로 취급: 애플리케이션의 로그는 파일에 저장하지 않고 표준 출력으로 처리되며, 로그 처리는 외부 도구에 위임(ex: ELK)해야함

12. 관리 프로세스 (Admin Processes)
관리 및 유지보수 작업을 일회성 프로세스로 실행: 데이터베이스 마이그레이션이나 배치 작업 같은 관리 작업은 일회성 프로세스로 실행되며, 애플리케이션의 주 프로세스와 분리된 독립적인 환경에서 실행