SPRING GATEWAY 를 이용한 MSA( 멀티 서비스, 멀티 서버 구현하기)

2025. 10. 20. 09:44·devops

목표

스프링 게이트웨이를 활용한 MSA 환경을 구축해본다.

과정

nginx 서버를 유지한 상태로 spring 서버 두기

  1. 스프링 서버 도커 이미지 준비

도커파일

FROM amazoncorretto:17-alpine AS builder
WORKDIR /app

COPY gradlew ./
COPY gradle ./gradle
COPY build.gradle settings.gradle ./

RUN ./gradlew dependencies --no-daemon || true

COPY src ./src

RUN ./gradlew clean bootJar -x test --no-daemon


FROM amazoncorretto:17-alpine
WORKDIR /app

COPY --from=builder /app/build/libs/*.jar app.jar

EXPOSE 8765

ENTRYPOINT ["java", "-jar", "app.jar"]

이미지 빌드

docker build -t lgcns-spring-rest-api:1.1.0 .
  1. nginx 설정 파일 수정
// default.conf
upstream blog_servs{
        server awsgoo-blog-1:8080;
}

server{
        listen 80;
        location / {
                proxy_pass http://blog_servs;
                proxy_set_header Host $host;
        }
}


Q. nginx 설정 파일에 Host 를 변경한 이유?

스프링 서버에서 받은 Host 의 값은 nginx 의 서버으로 바뀌고 여기서는 blog_servs 값을 가진다. 이 때, _ 는 스프링 서버에서 파싱을 못하는 이유가 있어 400 에러를 발생시킨다. 따라서, client 의 host 값으로 바꿔준다.
보통은 클라이언트의 host 값으로 바꿔주는데 가상 호스트, CORS, 리다이렉션 관련 문제가 발생할 수 있다.
가상 호스트: 서비스에서 가상 호스트와 관련된 로직이 있다면 수행하지 못할 수도 있다.
CORS: 클라이언트의 Origin 을 허용했지만 nginx 서버의 Origin 을 허용하지 않아 CORS 관련 에러가 발생할 수 있다.
리다이렉션: 엉뚱한 곳으로 리다이렉션 될 수 있다.

테스트 결과

$ curl http://localhost:9889/hello
{"koreaTime":"2025-10-16T02:13:51.346790465Z[GMT]","message":"Hello World!","timestamp":1760580831}

spring gateway 구성

  1. spring gateway project 준비
  1. 프로퍼티 파일 작성
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      server:
        webflux:
          routes:
            - id: hello_route
              uri: http://localhost:8765
              predicates: # 조건
                - Path=/hello # 경로 조건

            - id: abc2hello_route
              uri: http://localhost:8765
              predicates:
                - Path=/abc

            - id: def2hello_route
              uri: http://localhost:8765
              predicates:
                - Path=/def
              filters:
                - RewritePath=/def, /hello # /def 경로에 대한 요청에 대하여 path 를 변경하여 /hello로 보내기

테스트 결과

$ curl http://localhost:8080/hello
{"koreaTime":"2025-10-16T02:18:12.152314835Z[GMT]","message":"Hello World!","timestamp":1760581092}%                                                                                                

$ curl http://localhost:8080/abc
{"timestamp":"2025-10-16T02:18:16.764+00:00","status":404,"error":"Not Found","path":"/abc"}%    

$ curl http://localhost:8080/def
{"koreaTime":"2025-10-16T02:18:19.835062131Z[GMT]","message":"Hello World!","timestamp":1760581099}%     

spring-gateway 를 도커 컴포즈 파일에 포함시키기

  1. spring cloud gateay 를 도커 이미지로 빌드
$ docker build -t lgcns-sc-gateway .
  1. docker compose 파일 수정
scg-proxy:
    image: lgcns-sc-gateway
    ports:
      - "9000:9000"
    depends_on:
      - blog

1차 테스트 결과

$ curl http://localhost:9000/hello
{"timestamp":"2025-10-16T05:47:09.956+00:00","path":"/hello","status":500,"error":"Internal Server Error","requestId":"60a54f5c-2"}%

500 에러가 발생했다.

1차 테스트 결과 => 트러블 슈팅

먼저, 500(Internal Server Error)이므로 서버 로그를 확인한다.

2025-10-16T05:47:09.957Z ERROR 1 --- [sc-gateway] [ctor-http-nio-3] a.w.r.e.AbstractErrorWebExceptionHandler : [60a54f5c-2]  500 Server Error for HTTP GET "/hello"
2025-10-16 14:47:09 io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: localhost/127.0.0.1:8765
2025-10-16 14:47:09     Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
2025-10-16 14:47:09 Error has been observed at the following site(s):
2025-10-16 14:47:09     *__checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]
2025-10-16 14:47:09     *__checkpoint ⇢ HTTP GET "/hello" [ExceptionHandlingWebHandler]
2025-10-16 14:47:09 Original Stack Trace:
2025-10-16 14:47:09 Caused by: java.net.ConnectException: Connection refused

로그를 확인하니 뒷 단의 서버 연결을 맺고 있지 못한다. 뒷 단의 서버는 정상적으로 동작 중인데 왜 이런 에러가 발생했는지 확인한다.
설정 파일(프로퍼티 파일, 리소스 파일)을 확인해보면 다음과 같은 설정이 되어 있는 것을 확인할 수 있다.

routes:
  - id: hello_route
    uri: http://localhost:8765 # 뒷 단 서비스 uri
    predicates:
      - Path=/hello

원래는 호스트에서 앱을 실행해서 테스트를 했기 때문에 성공했지만 지금은 scg 를 컨테이너로 구동 중이다. 따라서, localhost 도메인은 컨테이너 자기 자신이 되므로 타 컨테이너로 요청을 보낼 수가 없는 것이다. 따라서, uri 를 다음과 같이 수정한다.

routes:
  - id: hello_route
    uri: http://awsgoo-blog-1:8080
    predicates:
      - Path=/hello

2차 테스트 결과

수정 후 다시 테스트를 해본다.

curl http://localhost:9000/hello
{"koreaTime":"2025-10-16T06:02:15.348718138Z[GMT]","message":"Hello World!","timestamp":1760594535}%

요청을 성공한 것을 확인할 수 있다.


Q. docker compose 작성 시 depends_on 주의 사항

docker compose 에서 컨테이너 순서를 control 하기 위해서 depends_on 이라는 명령을 사용한다. 하지만, depends_on 사용 시 주의할 점이 있다. 위처럼 단순히 depends_on: - blog 라고 한다면, 해당 서비스가 준비된 시점이 아니라 단순히 실행될 때에 해당한다.
완전히 준비된 상태에서 다른 컨테이너 구동될 필요가 있는 경우라면 이런 단순 depends_on 은 문제를 일으킬 수 있다. 그럴 때 사용할 수 있는 방법은 health_check 검사를 통해 해당 서비스가 준비되었는 지 확인한 후 구동하면 된다.
참고자료: Control startup and shutdown order in Compose

결론

nginx 를 Spring Cloud Gateway 로 대체하는 과정에 대해 학습하였다. Gateway를 통해 뒷 단의 서버로 라우팅할 수 있다. 보통은 eureka 서버와 함께 아키텍처를 구성하는 이유에 대해 생각해본다.

'devops' 카테고리의 다른 글

Spring Cloud Gateway 와 Spring Eureka 를 통해 MSA 환경 구축  (0) 2025.10.20
GW LB 를 이용한 무중단 배포(업데이트)  (0) 2025.10.20
nginx-proxy 이미지 없이 docker compose 를 활용하여 직접 MSA 구성  (0) 2025.10.20
docker 를 활용하여 직접 msa 구성  (0) 2025.10.20
docker compose 를 이용한 서비스 디스커버리 및 scale out - in  (0) 2025.10.15
'devops' 카테고리의 다른 글
  • Spring Cloud Gateway 와 Spring Eureka 를 통해 MSA 환경 구축
  • GW LB 를 이용한 무중단 배포(업데이트)
  • nginx-proxy 이미지 없이 docker compose 를 활용하여 직접 MSA 구성
  • docker 를 활용하여 직접 msa 구성
khw7385
khw7385
khw7385 님의 블로그 입니다.
  • khw7385
    khw7385 님의 블로그
    khw7385
  • 전체
    오늘
    어제
    • 분류 전체보기 (43) N
      • 코딩테스트 (7)
      • 자바 (3)
      • 스프링 (3)
      • cs (7)
        • 자료구조 (3)
        • 알고리즘 (1)
        • 객체지향 (3)
      • 개발일지 (6)
        • 트러블슈팅 (1)
      • 데이터베이스 (3)
        • Redis (2)
        • MySQL (1)
      • 기타 (2)
      • devops (6)
      • LG CNS AM INSPIRE (6) N
  • 블로그 메뉴

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

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
khw7385
SPRING GATEWAY 를 이용한 MSA( 멀티 서비스, 멀티 서버 구현하기)
상단으로

티스토리툴바