혼자서 공부하기에는 현재 진행중인 프로젝트도 이슈로 인해 조금 늘어지고, 어떠한 것을 공부하면 좋을 지 모르겠어서 방향성을 잃고 있던 상황에서 시간을 헛되이 보내는 것 같다고 생각해 내일배움캠프를 듣게 되었다.
다행히 완전 자바스프링 기초부터 진행하는 것은 아니고 기본적인 지식이 있는 상태에서 msa관련된 학습을 하는 내용으로 진행되기 때문에 내가 열심히만 하면 충분히 만족스러운 결과를 얻어갈 수 있을 것 같았다.
실제로 1주일 정도 진행을 했는데, 뭐랄까.. 무기력증에 빠져있던 시간이 후회될 정도로 의욕이 생겨나게 되었다. 추가로 CS관련 스터디도 진행하면서 조금 더 시간을 알차게 활용한다는 느낌이 들고 좋은 사람들을 만난 것 같아서 다행이라고 생각하고 있다.
따라서, 이번부터는 별도로 작성하고 싶은 내용이 없다면 내가 msa를 학습하는 과정에서 어떤 것을 배우고 있는지를 써서 기록으로 남기려고 한다. 실제로 주어진 강의를 1회독은 진행했는데, 새로운 개념 + 알아야하는 라이브러리 등이 많아지면서 1회독으로는 도저히 혼자서 학습하지 못할 것 같다고 생각해서 추가로 강의 다시 듣기 + 강의 내용 바탕으로 기본적인 학습 프로젝트 + 블로그 글 써서 기록으로 남기기 와 같이 진행하려고 한다.
MSA(MicroService Architecture)
우선 Spring Cloud에 대해서 알아보기 전에 이걸 활용하기 위한 MSA라는 개념부터 알아야 한다. 요즘은 신입 개발자를 뽑는 공고에도 우대 사항에 MSA 관련 프로젝트 경험 여부가 심심치 않게 적힌 것을 볼 수 있다.
MSA란 하나의 큰 애플리케이션을 여러 개의 작은 서비스로 쪼개서 개발하는 아키텍처 패턴이다. 각 서비스는 독립적으로 개발, 배포, 확장할 수 있으며 하나의 기술 스택에 국한되지 않고 서비스별로 서로 다른 기술 스택을 사용할 수도 있다.

MSA의 장점을 정리하면 다음과 같다.
- 각 서비스를 독립적으로 개발하고 배포할 수 있음
- 서비스 환경 / 팀원 구성에 따른 최적화된 기술 스택 선택 가능(즉, 하나의 기술에 종속되지 않는다)
- 장애가 발생하더라도 전체적인 서비스에 주는 영향을 최소화할 수 있다
- 서비스 팀별로 독립적인 개발 사이클을 가질 수 있음
지금까지 내가 개발해온 프로젝트는 모두 모놀리식 구조이다.

즉, 하나의 애플리케이션 안에 모든 기능이 들어있는 형태이다. 모놀리식 구조의 단점을 뽑아보자면
- 아주 작은 사항이라도 기능이 변경될 경우 전체 애플리케이션을 재배포 해야 함
- 한 번 선택한 언어 및 프레임워크를 강제로 모든 개발자가 사용해야 함. 다른 스택을 개발하던 사람이 유지보수를 맡게 되면 이에 해당하는 기술 스택을 학습해야 한다.
- 또한 하나의 repository를 사용하기 때문에, 브랜치 전략을 잘 가져가더라도 충돌 발생 여부 등을 더 신경써야 한다.
이렇게 단점만 뽑아보면 굳이 모놀리식을 적용할 필요 없이 모두 MSA로만 작성하면 좋지 않을까? 라고 생각할 수 있지만 현실은 달랐다.
우선 가장 큰 러닝 커브, 분산 환경 간 데이터 일관성 문제, 디버깅의 어려움 등 고려해야 하는 상황이 많다는 것을 알 수 있었다.
Spring Cloud
이러한 MSA의 복잡성을 해결하기 위해 나온 것이 Spring Cloud다. 마이크로서비스 개발을 위해 다양한 도구와 서비스를 제공하고, 마이크로서비스 아키텍쳐를 쉽게 구현하고 운영할 수 있도록 도와준다.
Spring Cloud의 주요 기능
- Service Discovery: 서비스 탐색(Eureka, Consul, Zookeeper)
- Load Balancing: 인스턴스 부하 분산(Ribbon, Spring Cloud LoadBalancer)
- Circuit Braking: 장애 전파 방지(Hystric, Resilience4j)
- Configuration Management: 구성 관리(Spring Cloud Config)
- API Gateway: 외부 요청 라우팅(Zuul, Spring Cloud Gateway)
- Distributed Tracing: Spring Cloud Sleuth, Zipkin
- Messaging: 메시징(Spring Cloud Stream)
Eureka
Eureka는 넷플릭스가 개발한 서비스 디스커버리 서버로, 마이크로서비스 아키텍쳐에서 각 서비스의 위치를 동적으로 관리할 수 있다.
왜 Service Discovery가 필요할까?
모놀리식의 경우 하나의 프로젝트 안에서 다른 기능을 호출하기 위해 메서드 호출, 조금 더 복잡하게는 로컬 HTTP 요청 등으로 충분히 데이터를 교환할 수 있었다. 하지만 MSA에서는 각 서비스별로 독립적인 환경으로 구성되어 있기 때문에 우선 다른 서비스를 호출하기 위해서는 다른 서비스가 어디에 위치하고 있는지부터 알아야 한다.
그렇다고 서비스의 호스트, 포트 등을 하드코딩해서 매번 수기로 입력할 수 없고, 하나의 서비스가 여러 개의 인스턴스로 분산되어 있을 수 있으며 만약 하나의 서버라고 하더라고, 해당하는 서비스가 다운됐을 경우 이를 파악할 수가 없다.
따라서 이러한 문제를 해결하기 위해 Service Discovery가 등장하게 되었다.
Eureka의 주요 특징
- 서비스 레지스트리: 모든 서비스 인스턴스의 위치를 저장하는 중앙 저장소
- 헬스 체크: 서비스 인스턴스의 상태를 주기적으로 확인하여 가용성을 보장한다.
Eureka의 동작 원리
Eureka는 `Eureka Server`와 `Eureka Client`로 구성된다:
Eureka Server (Service Registry)
- 서비스들의 정보를 등록하고 관리하는 중앙 저장소
- 각 서비스의 위치, 상태, 메타데이터를 보관
- 웹 대시보드를 통해 등록된 서비스들을 확인할 수 있음
Eureka Client
- 실제 마이크로서비스에 포함되는 라이브러리
- 시작할 때 Eureka Server에 자신을 등록
- 주기적으로 heartbeat를 보내서 살아있음을 알림
- 다른 서비스를 호출할 때 Eureka Server에서 위치 정보를 조회
실제로 구성해보자

우선, 우리가 추가할 라이브러리는 https://start.spring.io/ 을 통해서 `Eureka Discovery Client`, `Eureka Server` 등으로 쉽게 검색이 가능하다.
ext {
set('springCloudVersion', "2025.0.0")
}
// Eureka Discovery Client
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
// Eureka Server
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
Eureka Server 설정


ServerApplication에 `EnableEurekaServer`을 등록하거나, 아니면 별도의 Config 파일로 구성하자. 나는 메인 위에 어노테이션이 달리는 것을 별로 좋아하지 않아 별도의 Config 파일로 작성했다.
그 다음은 application.yml 파일 작성이다. msa에 관련된 많은 부분들이 이 application.yml을 잘 작성할 줄 아느냐로 갈리는 것 같다는 생각도 하게 됐다.

이렇게 설정하고 실행한 뒤 접속해보면

위와 같은 화면을 볼 수 있는데, 아직 설정된 서비스가 없어서 No instances available이라고 나온다.
테스트용으로 user-service를 하나 만들어서 테스트해보자.
Eureka Client 설정
의존성을 추가하고 application.yml에 설정을 해주자

그 후에 실행을 하고 다시 8761번 포트를 확인해보면

서비스 디스커버리에서 정상적으로 인스턴스를 등록한 부분을 확인할 수 있었다.
사실, 블로그 글을 처음 연재한 이후로 단순 설정, 코드와 같은 부분은 양만 늘리고 불필요하다고 생각해서 내 생각의 흐름과 사고를 위주로 작성했었다. 그런데 MSA 부분은 까먹을 것 같은 일이 너무 많아서 이러한 내용을 우선 추가하고 추후 학습을 모두 완료하면 기존의 방식처럼 돌아가보려 한다.
'Back-End' 카테고리의 다른 글
| MSA 학습 - 서킷 브레이커 (0) | 2025.09.24 |
|---|---|
| MSA 학습 - 로드밸런싱(FeignClient, Ribbon) (0) | 2025.09.23 |
| 비동기 메시징 방식(RabbitMQ vs Kafka) (0) | 2025.09.19 |
| @Transactional(readOnly=true)는 왜 써야하는걸까? (0) | 2025.09.18 |
| [JPA] 외래키 주인으로 알아보는 엔티티 연관관계 (0) | 2025.09.17 |