들어가며
현대의 복잡한 비즈니스 요구사항을 만족시키기 위해, 많은 기업들이 모놀리식 아키텍처에서 마이크로서비스 아키텍처(MSA, Microservices Architecture)로 전환하고 있습니다. 이번 글에서는 Spring Cloud Netflix 스택을 기반으로 한 전형적인 MSA 구조를 살펴보고, 각 구성요소의 역할과 상호작용에 대해 자세히 알아보겠습니다.
마이크로서비스 아키텍처는 하나의 큰 애플리케이션을 여러 개의 작고 독립적인 서비스로 분해하는 설계 패턴입니다. 각 서비스는 특정 비즈니스 기능을 담당하며, 독립적으로 개발, 배포, 확장될 수 있습니다.
Eureka Server는 Netflix에서 개발한 서비스 디스커버리 도구로, MSA 환경에서 서비스 등록과 발견을 담당합니다.
서비스 등록 (Service Registration)
각 마이크로서비스는 시작될 때 자신의 정보(IP, 포트, 서비스명 등)를 Eureka Server에 등록합니다. 이를 통해 다른 서비스들이 해당 서비스를 찾을 수 있게 됩니다.
서비스 발견 (Service Discovery)
클라이언트 서비스는 다른 서비스를 호출할 때 하드코딩된 IP와 포트 대신 서비스명을 사용합니다. Eureka가 실제 인스턴스 정보를 제공하여 동적인 서비스 호출을 가능하게 합니다.
헬스 체크 (Health Check)
등록된 서비스들의 상태를 주기적으로 확인하여, 장애가 발생한 인스턴스를 자동으로 제거합니다. 이를 통해 항상 건강한 서비스 목록을 유지합니다.
로드 밸런싱
동일한 서비스의 여러 인스턴스가 있을 때, 요청을 적절히 분산시켜 성능을 최적화합니다.
# Eureka Server 설정
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
Config Server는 분산 시스템에서 설정 정보를 중앙에서 관리할 수 있게 해주는 Spring Cloud의 핵심 구성요소입니다.
설정 분산 문제 해결
마이크로서비스가 많아질수록 각 서비스의 설정 파일을 개별적으로 관리하는 것은 매우 번거롭습니다. Config Server를 사용하면 모든 설정을 한 곳에서 관리할 수 있습니다.
환경별 설정 관리
개발, 테스트, 프로덕션 환경별로 다른 설정값을 쉽게 관리할 수 있습니다. Git 브랜치나 프로파일을 활용하여 환경별 설정을 분리할 수 있습니다.
실시간 설정 변경
서비스를 재시작하지 않고도 설정값을 동적으로 변경할 수 있습니다. Spring Cloud Bus와 함께 사용하면 모든 서비스에 설정 변경사항을 실시간으로 전파할 수 있습니다.
# Config Server 설정
server:
port: 8888
spring:
cloud:
config:
server:
git:
uri: https://github.com/your-org/config-repo
search-paths: config
API Gateway는 클라이언트와 마이크로서비스 사이의 중간 계층으로, 모든 요청의 단일 진입점 역할을 합니다.
요청 라우팅
클라이언트의 요청을 적절한 마이크로서비스로 라우팅합니다. URL 패턴, 헤더, 파라미터 등을 기반으로 지능적인 라우팅이 가능합니다.
인증 및 권한 부여
모든 요청에 대한 인증과 권한 검사를 중앙에서 처리합니다. JWT 토큰 검증, OAuth 인증 등을 통해 보안을 강화할 수 있습니다.
부하 분산
동일한 서비스의 여러 인스턴스 간에 요청을 분산시켜 시스템의 가용성과 성능을 향상시킵니다.
응답 변환 및 집계
여러 서비스의 응답을 조합하거나 변환하여 클라이언트에게 최적화된 형태로 제공할 수 있습니다.
모니터링 및 로깅
모든 API 호출을 중앙에서 모니터링하고 로깅할 수 있어, 시스템 전체의 상태를 파악하기 쉽습니다.
속도 제한 (Rate Limiting)
API 호출 빈도를 제한하여 시스템을 남용으로부터 보호합니다.
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- RewritePath=/api/users/(?<segment>.*), /users/${segment}
- id: order-service
uri: lb://order-service
predicates:
- Path=/api/orders/**
나머지 서비스들은 실제 비즈니스 로직을 처리하는 마이크로서비스들입니다. 각각은 특정 도메인을 담당하며 독립적으로 운영됩니다.
동기 통신
HTTP REST API를 사용한 실시간 통신으로, 즉시 응답이 필요한 경우에 사용합니다. Spring Cloud OpenFeign을 활용하면 선언적인 방식으로 서비스 간 통신을 구현할 수 있습니다.
비동기 통신
메시지 큐(RabbitMQ, Apache Kafka)를 사용한 이벤트 기반 통신으로, 느슨한 결합과 높은 확장성을 제공합니다.
독립적 개발 및 배포
각 팀이 서로 다른 서비스를 독립적으로 개발하고 배포할 수 있어 개발 속도가 향상됩니다.
기술 스택 자유도
서비스별로 최적의 기술을 선택할 수 있어 기술적 혁신을 촉진합니다.
확장성
트래픽이 많은 서비스만 선택적으로 확장할 수 있어 리소스를 효율적으로 사용할 수 있습니다.
장애 격리
한 서비스의 문제가 전체 시스템에 영향을 주지 않아 시스템 안정성이 향상됩니다.
마치며
MSA는 Eureka, Config Server, API Gateway 같은 핵심 구성요소들이 유기적으로 결합되어 확장 가능하고 유연한 시스템을 만들어줍니다.
각 서비스가 독립적으로 개발되고 배포될 수 있다는 것은 큰 장점이지만, 동시에 분산 시스템의 복잡성과 운영 부담도 함께 따라오기 때문에 MSA 도입시 각 서비스에 맞춰 설계하여야 합니다.