Spring Boot 마이크로서비스 프로젝트 구축: 아키텍처, 워크플로우, 그리고 학습
Source: Dev.to
소개
지난 몇 주 동안 나는 Spring Boot와 Spring Cloud를 사용하여 실제 분산 시스템이 어떻게 설계되고 구축되는지를 깊이 이해하기 위해 백엔드 마이크로서비스 프로젝트를 진행했습니다. 단일 모놀리식 애플리케이션을 만드는 대신, 시스템을 더 작고 독립적인 서비스들로 나누어 각각이 진화하고, 확장되며, 독립적으로 실패할 수 있도록 하는 것이 목표였습니다. 이 글에서는 아키텍처, 전체 워크플로우, 그리고 프로젝트를 구축하면서 얻은 주요 기술적 학습 내용을 살펴봅니다.
시스템 개요
시스템은 채용 포털 스타일 백엔드로 설계되었으며, 여러 마이크로서비스로 구성됩니다. 각 마이크로서비스는 자체 데이터베이스를 보유하고 단일 비즈니스 기능을 담당하여 서비스 경계, 데이터 격리 및 느슨한 결합을 강화합니다.
핵심 서비스
| 서비스 | 책임 |
|---|---|
| Job Service | 채용 공고 관리 (생성, 업데이트, 채용 조회) |
| Company Service | 회사 프로필 및 관련 데이터 관리 |
| Review Service | 회사 리뷰 및 평점 처리 |
각 서비스는 자체 데이터베이스 스키마를 가진 독립적인 Spring Boot 애플리케이션이며, 별도로 배포 및 실행됩니다.
지원 인프라
| Component | 목적 |
|---|---|
| Spring Cloud Gateway | 모든 클라이언트 요청에 대한 단일 진입점 |
| Eureka Server | 서비스 검색 |
| OpenFeign | 동기식 서비스 간 통신 |
| RabbitMQ | 비동기식, 이벤트 기반 통신 |
| Spring Cloud Config Server | 중앙 집중식 구성 관리 |
| Docker | 각 마이크로서비스를 컨테이너화 |
| Kubernetes (K8s) | 컨테이너 오케스트레이션 |
API 게이트웨이를 통한 요청 흐름
모든 클라이언트 요청은 먼저 API 게이트웨이에 도달하며, 게이트웨이는 라우팅을 처리하고 요청 경로에 따라 적절한 마이크로서비스로 요청을 전달합니다. 이는 클라이언트가 여러 서비스 URL/포트를 알 필요 없게 하여 클라이언트 측 로직을 단순화하고 보안을 향상시킵니다.
- 게이트웨이는 Eureka Server에 질의하여 대상 서비스의 사용 가능한 인스턴스를 발견합니다.
- 요청은 올바른 마이크로서비스(Job, Company, 또는 Review Service)로 라우팅됩니다.
- 각 마이크로서비스는 요청을 독립적으로 처리하고 자신만의 데이터베이스와만 상호작용합니다.
예시: 회사 정보와 함께 채용 상세 조회
- 클라이언트는 게이트웨이를 통해 Job API를 호출합니다.
- Job Service는 자신의 데이터베이스에서 채용 데이터를 조회합니다.
- OpenFeign을 사용하여 Job Service가 Company Service를 동기식으로 호출해 회사 상세 정보를 가져옵니다.
- 집계된 응답이 클라이언트에 반환됩니다.
RabbitMQ를 이용한 비동기 통신
이벤트‑드리븐 아키텍처를 탐색하기 위해, 특정 작업(예: 핵심 엔티티 생성 또는 업데이트)이 RabbitMQ에 이벤트를 발행합니다. 다른 서비스는 생산자와 긴밀히 결합되지 않은 상태로 이러한 이벤트를 소비할 수 있어 복원력, 확장성 향상 및 직접적인 의존성을 감소시킵니다. 이 구현을 통해 다음을 이해하게 되었습니다:
- 메시지 큐, 생산자, 그리고 소비자
- 최종 일관성
중앙 집중식 구성
Spring Cloud Config Server는 모든 애플리케이션 속성을 중앙에 저장합니다. 각 마이크로서비스는 시작 시 구성 서버에서 설정을 가져와, 구성 변경을 더 쉽고 전체 생태계에 걸쳐 일관되게 만들 수 있습니다.
Observability
분산 환경에서 디버깅 및 모니터링을 위해 다음을 살펴보았습니다:
- Centralized logging → 중앙 집중식 로깅
- Distributed tracing (using Zipkin‑compatible tracing configuration) → 분산 추적 (Zipkin 호환 추적 구성 사용)
이러한 도구들은 요청이 여러 서비스에 걸쳐 이동할 때 추적을 간소화합니다.
컨테이너화 및 오케스트레이션
모든 마이크로서비스가 Docker화되어 시스템이 다양한 환경에서 일관되게 실행될 수 있습니다. Kubernetes 매니페스트가 다음을 위해 생성되었습니다:
- 서비스를 배포하고 내부에 노출한다
- 스케일링을 관리한다
- 파드, 서비스, 포트 매핑 및 서비스 디스커버리를 처리한다
Kubernetes를 사용함으로써 단일 클러스터 내에서 다수의 마이크로서비스를 배포하는 실무 경험을 얻을 수 있었습니다.
저장소
전체 소스 코드는 다음에서 확인할 수 있습니다:
주요 내용
- 적절한 서비스 경계를 설계하면 결합도가 높아지는 것을 방지할 수 있습니다.
- 동기(OpenFeign)와 비동기(RabbitMQ) 통신의 차이를 이해합니다.
- API 게이트웨이는 클라이언트와의 상호작용을 단순화하고 보안을 강화하는 데 필수적입니다.
- 서비스 디스커버리는 동적 환경을 가능하게 합니다.
- 중앙 집중식 구성은 분산 시스템에서 관리을 단순화합니다.
- 실제로는 서비스 간 지연, 디버깅, 구성 관리와 같은 과제가 명확히 드러납니다.
이 프로젝트를 구축하면서 Spring Boot와 Spring Cloud를 활용한 현대적인 백엔드 아키텍처에 대한 확고한 기반을 다졌으며, 특정 도구와 패턴이 존재하는 이유를 명확히 이해하게 되었습니다—단순히 사용 방법을 넘어.