[내일배움캠프 본캠프] 11일 차 TIL MSA, Git flow

2026. 2. 20. 16:48·내배캠

11차 TIL

MSA의 전체적인 동작 흐름에 대해서 배우고, Git의 협업 방법 중 하나인 Git flow에 대해서 배웠다.

 

오늘은 서비스를 분리/호출하는 방법, 즉 서비스 디스커버리인 Eureka + FeignClient와 로드밸런싱에 대해서 배웠다면
내일은 에러 시 대응할 서킷 브레이커인 Resilience4j와 유저가 호출을 처리하는 API Gateway에 대해서 배울 것 같다.

MSA

MSA는 하나의 애플리케이션을 여러 개의 독립적인 서비스로 나눠 분리하여 개발하는 아키텍처 스타일이다.

즉 하나의 Spring boot 코드 베이스 안에서 진행하던 프로젝트를
여러 개의 Spring boot 애플리케이션으로 나눠
각 서비스만을 분리하여 개발하는 것을 뜻한다.

이때 하나의 Spring boot 코드 베이스 안에서 개발하는 것을 모놀리틱 아키텍처라고 부른다.
이에 따라서, 분리된 각 애플리케이션들은 각자의 DB를 가진다.

MSA 등장 배경

서비스가 커짐에 따라서 특정 기능을 수정했을 때, 다른 기능들까지 영향을 미칠 수 있다.

서비스를 나눠 분리하여 개발했을 때, 배포 시 다른 서비스에 영향을 주지 않고 업데이트할 수 있다.
또한 각 서비스는 기술 스택을 자유롭게 선택할 수 있다.

Spring Cloud

넷플릭스(Netflix)측에서 더 이상 업데이트 하지 않는 유지보수(Maintenance) 상태로 전환한 기술들이 있다.
그 부분들은 빨간색글자로 표시했다.

 

- 서비스 디스커버리

1. Eureka : 각 서비스의 위치를 동적으로 관리

2. Ribbon : 로드 밸런서, 서비스 인스턴스 간 부하를 분산 => Spring Cloud LoadBalancer가 대체함

 

- 서킷브레이커

1. Hystrix : 서비스 간 호출 실패를 감지, 안정성 유지 => Resilience4j가 거의 대체

2. Resilience4j : 자바 기반의 서킷 브레이커, Hystrix의 대안으로 등장

 

- API 게이트웨이

1. Zuul : 모든 서비스 요청을 중앙에서 관리 ( 넷플릭스 ) => Spring Cloud Gateway가 거의 대체

2. Cloud gateWay : 스프링 클라우드에서 제공하는 API 게이트웨이

 

- 구성관리

1. Spring Cloud config : 중앙 집중식 설정 관리를 제공
=> Config 서버 : 중앙에서 설정 파일 관리, 각 서비스에 제공
=> Config 클라이언트 : Config 서버에서 설정을 받아서 사용하는 서비스

 

- 분산 추적
1. zipkin : 서비스 호출의 흐름을 파악하게 해 줌

 

- Spring Cloud의 흐름, 구성도

그림판으로 그려본 Spring Cloud의 흐름, 구성도

낙서처럼 보이지만 나름대로 나중에 보면 기억날 것 같다.

Eureka

Eureka는 서비스 디스커버리 기능을 수행한다.
서비스 디스커버리는 MSA에서 각 서비스의 위치를 동적으로 관리하고 찾아준다.
=> 서비스 등록/조회, 헬스 체크

전화번호부를 관리하는 Eureka Server
전화번호를 등록하는 Eureka Client


실제 호출은 FeignClient를 사용한다.

FeignClient로 host와 상세 경로와
어떻게 요청을 보낼 지(파라미터 등)를 설정한다.

만약 RestTemplate을 사용한다면?


- RestTemplate 예시

1. RestTemplate을 수동으로 Bean을 등록하고, 그 Bean에 @LoadBalanced을 부착시켜 사용한다.

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

2. RestTemplate의 메서드 파라미터로 url을 넘겨줌

@RestController
public class MyRestTemplateController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/get-data-rest")
    public String getDataWithRestTemplate() {
        String serviceUrl = "http://my-service/api/data";
        return restTemplate.getForObject(serviceUrl, String.class);
    }
}

 

만약 FeignClient 사용한다면?

1. Application에 @EnableFeignClients 부착

@SpringBootApplication
@EnableFeignClients
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

2. @FeignClient의 name 옵션으로 요청을 보낼 서비스의 호스트를 적고
메서드를 생성하고 상세 엔드포인트를 적는다.
이때 컨트롤러에서 설정하듯이 @RequestParam, @PathVariable 등을 적어 파라미터를 설정한다.

즉, HTTP 요청을 만드는 부분?

@FeignClient(name = "my-service")
public interface MyServiceClient {

    @GetMapping("/api/data")
    String getData();
}

3. 사용할 컨트롤러에서 서비스의 메서드 호출 -> 서비스에서 2에서 만든 메서드 호출

@RestController
public class MyFeignClientController {

    @Autowired
    private MyServiceClient myServiceClient;

    @GetMapping("/get-data-feign")
    public String getDataWithFeignClient() {
        return myServiceClient.getData();
    }
}

 

즉, RestTemplate과 FeignCleint의 차이는 컨트롤러에서 경로를
직접 url 작성 + http 요청 구성  vs 인터페이스 기반 호출

정리해서 말하면
명령형 vs 선언형이라고 볼 수 있다.

+) 헬스체크의 기본 경로 /actuator/health

Eureka 사용 시 설정법

서버와 클라이언트 공통 설정)

1. port번호 설정
2. 어디에서 관리할지를 적는다.

서버 설정

1. 유레카 서버로부터 자신을 등록하지 않는다.
2. 유레카 서버로부터 레지스트리를 가져오지 않는다.

3. 서비스들이 호출할 호스트명을 적는다.

4. 어디에서 서비스들을 관리할 지 주소를 적는다.
+) Application에 본인이 Eureka 서버라는 것을 알리기 위해 @EnableEurekaServer 부착

spring.application.name=server

server.port=19090

# 유레카 서버에 자신을 등록할지 여부를 설정합니다.
# true로 설정하면 유레카 클라이언트가 유레카 서버에 자신을 등록합니다.
# 유레카 서버에서는 일반적으로 false로 설정하여, 서버가 자기 자신을 등록하지 않도록 합니다.
eureka.client.register-with-eureka=false

# 유레카 서버로부터 레지스트리를 가져올지 여부를 설정합니다.
# true로 설정하면 유레카 클라이언트가 유레카 서버로부터 다른 서비스 인스턴스 목록을 가져옵니다.
# 유레카 서버에서는 일반적으로 false로 설정하여, 레지스트리를 가져오지 않도록 합니다.
eureka.client.fetch-registry=false

# 유레카 서버 인스턴스의 호스트 이름을 설정합니다.
# 유레카 서버가 자신의 호스트 이름을 다른 서비스에 알릴 때 사용합니다.
eureka.instance.hostname=localhost

# 유레카 클라이언트가 유레카 서버와 통신하기 위해 사용할 기본 서비스 URL을 설정합니다.
# 클라이언트 애플리케이션이 유레카 서버에 연결하고 등록하거나 레지스트리를 가져올 때 사용할 URL을 지정합니다.
eureka.client.service-url.defaultZone=http://localhost:19090/eureka/

클라이언트 설정

공통 설정만 하면 된다.

spring.application.name=second

server.port=19092

# 유레카 클라이언트가 유레카 서버와 통신하기 위해 사용할 기본 서비스 URL을 설정합니다.
# 유레카 서버의 포트와 호스트 이름을 정확히 지정해야 합니다.
eureka.client.service-url.defaultZone=http://localhost:19090/eureka/

로드 밸런싱

클라리언트 사이드 로드 밸런싱
- 클라이언트가 직접 여러 서버 중 하나를 선택해서 요청을 보냄

FeignClient란?
Eureka와 같은 서비스 디스커버리와와 연동해서 서비스 인스턴스를 조회하고 로드 밸런싱을 수행한다.

Ribbon이 통합되어 있어서 자동으로 로드 밸런싱을 수행한다.

Ribbon이란?

서비스 인스턴스 간의 부하를 분산
다양한 로드 밸런싱 알고리즘을 지원하며 Eureka와 같은 서비스 디스커버리와 연동하여 사용한다.

Eureka 등으로부터 서비스 인스턴스를 제공받아 로드 밸런싱에 사용
라운드 로빈, 가중치 기반 등의 로드 밸런싱 알고리즘 지원

라운드 로빈은 인스턴스를 번갈아가면서 실행함.
Product의 포트가 3개라면?
order에서 product 서비스 호출 시
19092 -> 19093 -> 19094
순서로 실행

 

- 의존성

dependencies {
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
    implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
}

 

Eureka-client
openfeign 추가

 

- 사용 방법
1. FeignClient 인터페이스를 생성한다.

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(name = "my-service")
public interface MyServiceClient {

    @GetMapping("/endpoint")
    String getResponse(@RequestParam(name = "param") String param);
}

 

- name 옵션으로 가져올 애플레케이션 서버의 서비스 ID를 지정한다.
- HTTP 요청을 보낼 서버의 엔드포인트와 요청 정보를 적는다. ( 메서드명은 일치시킬 필요 없음 )

 

2. 컨트롤러에서는 기존과 동일하게 호출한다.

import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class OrderController {
    private final OrderService orderService;

    @GetMapping("/order/{orderId}")
    public String order(@PathVariable("orderId") String orderId) {
        return orderService.getOrder(orderId);
    }
}

3. 서비스 레이어에서 @FeignClient를 사용한 인터페이스의 메서드를 호출해서 해당 서버로 요청을 보낸다.

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class OrderService {
    private final ProductClient productClient;

    public String getProductInfo(String productId) {
        return productClient.getProduct(productId);
    }

    public String getOrder(String orderId) {
        if(orderId.equals("1")){
            String productId = "2";
            String productInfo = productClient.getProduct(productId);
            return "Your order is "+ orderId + " and " + productInfo;
        }else{
            return "Not exist order...";
        }
    }
}

Git Flow

master - 배포 버전

release - 배포 준비 중, 완료 시 master와 develope에 병합

develope - 새로운 기능 개발의 중심 브랜치

feature - devlelope에서 분기, 새로운 기능 구현 후 develope으로 병합

hotfix - 긴급한 문제를 해결 후 바로 master와 develope에 둘 다 병합 후 배포

 

merge -> 새로운 커밋을 추가하여 브랜치를 합침, 각 브랜치의 커밋이 남음

rebase -> 특정 브랜치 위로 커밋을 적용해서 합침, 하나의 브랜치에서 작업한 것처럼 보임

'내배캠' 카테고리의 다른 글

[내일배움캠프 본캠프] 13일 차 TIL 상품-주문 MSA 프로젝트  (0) 2026.02.22
[내일배움캠프 본캠프] 12일 차 TIL MSA  (0) 2026.02.21
[내일배움캠프 본캠프] 10일 차 TIL Spring AI  (0) 2026.02.19
[내일배움캠프 본캠프] 9일 차 TIL 소셜 로그인(OAuth), 단위 테스트, AOP, 예외 처리  (0) 2026.02.18
[내일배움캠프 본캠프] 8일 차 TIL 페이징처리, 다대다, AWS  (0) 2026.02.17
'내배캠' 카테고리의 다른 글
  • [내일배움캠프 본캠프] 13일 차 TIL 상품-주문 MSA 프로젝트
  • [내일배움캠프 본캠프] 12일 차 TIL MSA
  • [내일배움캠프 본캠프] 10일 차 TIL Spring AI
  • [내일배움캠프 본캠프] 9일 차 TIL 소셜 로그인(OAuth), 단위 테스트, AOP, 예외 처리
MvA
MvA
백엔드 개발자 김재현입니다. 주로 공부하면서 느낀점을 기록합니다.
  • MvA
    Man vs Ai
    MvA
  • 전체
    오늘
    어제
    • 분류 전체보기 (94)
      • Java (6)
      • Python (8)
        • 딥러닝 (1)
        • 머신러닝 (7)
      • JavaScript (2)
      • 내배캠 (60)
      • 개인 프로젝트 (11)
      • 책 후기 (5)
      • 기타 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    딥러닝
    아키텍처
    머신러닝
    내일배움캠프
    Riot API
    TiL
    배포
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
MvA
[내일배움캠프 본캠프] 11일 차 TIL MSA, Git flow
상단으로

티스토리툴바