관리 메뉴

백엔드 엔지니어 이재혁

[MSA 전환기] Day 1 - 설계, API Gateway 만들기 본문

케어매칭 서비스 배포

[MSA 전환기] Day 1 - 설계, API Gateway 만들기

alex00728 2025. 10. 30. 19:53

케어매칭 프로젝트를 서비스에 적합한 MSA 아키텍처로 전환해보고자 한다.

 

아키텍처 설계

각 서비스 분리 이유

1. 채팅 서비스 (Chat Service)

상황 Spring MVC Node.js
채팅 발송 요청마다 스레드 할당 싱글 스레드 유지 (이벤트 루프 기반 작업)

 

채팅 서비스는 작은 요청이 많이 들어온다. 요청마다 실질적인 처리 비용은 낮지만, Spring MVC에서는 많은 요청 때문에 스레드가 많이 생긴다. Node.js를 이용해 스레드의 컨텍스트 스위칭 비용을 최소화하자.

채팅은 네트워크 I/O가 많으니, 실제 구현시에는 오버헤드가 적은 라이브러리도 찾아보자.


2. 결제 서비스 (Transaction Service)

결제 서비스의 경우, 시스템의 기술적인 성능보다는 도메인의 중요성 때문에 나눠보고자 했다.

결제 서비스가 다른 시스템으로부터 장애가 격리될 수 있도록 하고, 결제 시스템 장애 발생시 즉시 "결제 시스템"이 장애라는 점을 인지할 수 있을 것이다.

 

3. 결제 복구 시스템 (Transaction Recovery)

결제 복구 시스템은 항상 실행되어야 하는 시스템이 아니다.

PG사의 일시적인 장애가 발생했을 때, 장애 복구 직후, 밀려있던 작업을 처리해주기 위한 시스템이다.

필요할 때만 실행될 수 있도록 하는데는 AWS Lambda가 적합하다고 생각했고, Cold Start 할 때도 즉시 실행하기 위해 Node.js 기반으로 해야 빠르게 실행할 수 있을 것이라고 생각했다.

 

 

API Gateway도 수평 확장 가능하게

API Gateway도 수평 확장이 필요할까? 라는 고민을 했다.

없어도 되는가? API 게이트웨이는 사실 단순히 요청을 전달해주기만 하는 일을 하기 때문에 부하가 크지는 않을 것

있어야 하는가? API 게이트웨이는 전체 시스템과 사용자를 이어주는 단일 장애점.

 

기술적인 효용성보다는 단일 장애점 극복이 더 중요한 문제라고 판단해 수평 확장을 할 수 있게 만들었다 (ALB 사용) AWS의 Auto-Scaling을 활용해 필요할 때만 확장하면 비용이 크지는 않을 것.

 

MSA 밑바닥 다지기

  • MSA 시스템을 구성하기 전에, API Gateway 추가
  • 기존 모놀로식 서비스를 최대한 건들지 않는 선으로 유지

 

프로젝트에 디렉토리 추가

모노레포 유지 - 기존 디렉토리 구조는 그대로 두고, infra 디렉토리를 만들어서 Spring Cloud Gateway 구성

infra/
└─ gateway/
  ├─ build.gradle
  ├─ src/main/java/
  │ ├─ com/sesac/carematching/infra/gateway/
  │ └─ GatewayApplication.java
  └─ resources/
    └─ application.yaml

 

루트 디렉토리에 `settings.gradle` 추가

rootProject.name = 'carematching'

include ':infra:gateway'

 

이렇게 `settings.gradle`을 구성하면 하나의 디렉토리 안에서 다른 모듈도 실행할 수 있다.

 

실행: `./gradlew :infra:gateway:bootRun`

빌드: `./gradlew :infra:gateway:build`

 

포트 변경

Gateway 서버: 8080

기존 서버: 8080 → 8081

 

Gateway application.yaml 설정

server:
  port: 8080

spring:
  cloud:
    compatibility-verifier:
      enabled: false
    gateway:
      routes:
        - id: carematching-service
          uri: "${carematching.backend.uri:http://localhost:8081}"
          predicates:
            - Path=/carematching/**
          filters:
            - StripPrefix=1 # 경로의 첫 번째 세그먼트 제거 (숫자가 늘어나면 제거하는 경로의 깊이가 늘어남)
application:
  name: gateway

 

 

Gateway를 통해 백엔드 접속 확인

`http://localhost:8080/carematching/api/v1/caregivers`로 접속하니, 8081에서 실행 중인 서버의 응답이 잘 왔다.

 

오늘의 마무리

MSA 시스템의 밑바닥을 만든 날.

 

이제 carematching 서비스에서 떼어내고 싶은 부분을 Micro Service로 만든 다음, 기존 모놀로식 서버에서 해당 로직을 제거하면 된다.