Spring

Spring Cloud Gateway 연동

코드파고 2025. 1. 11. 00:29

모듈이 늘고 인증에 대한 중앙화와 라우팅에 대한 필요성을 느껴 Cloud Gateway를 도입해보도록 한다.
현재 생태계는 Spring이기 때문에 Spring Cloud Gateway를 도입하였다.

각 모듈, API의 독립성을 유지해 주는 점에 있어서는 좋으나,
아무래도 요청이 밀집될 수 있기 때문에 Gateway의 부하 분산에 대한 고민이 필요할 것 같다.

<작업 환경>

Spring Version : 3.4.1
Java : 17

Spring Gateway 환경 설정

build.gradle

ext {
    set('springCloudVersion', "2024.0.0")
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    implementation 'org.springframework.cloud:spring-cloud-starter-gateway'

    implementation 'io.netty:netty-resolver-dns-native-macos:4.1.68.Final:osx-aarch_64' // Jetty MAC DNS 설정을 위한 의존성

    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'io.projectreactor:reactor-test'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

application.yml

CORS 설정에 유의하며 작성하도록 하자

spring:
  cloud:
    gateway:
      globals:
        add-to-simple-url-handler-mapping: true
        # CORS 사전 실행 요청(Preflight Request)을 위한 OPTIONS 설정
        cors-configurations:
          '[/**]':
            allowedOrigins: "*"
            allowedMethods: GET, POST, PUT, DELETE, OPTIONS
            allowedHeaders: "*"
            allowCredentials: true
      default-filters:
        - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
        # Access-Control-Allow Credentials, Access-Control-Allow-Origin 의 중복 방지

 

CORS 설정

타겟 서버(API) CORS 설정을 추가해 두었다.

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class GlobalCorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*")
                .allowedHeaders("*")
                .allowedMethods("GET", "POST", "PATCH", "PUT", "DELETE", "PATCH", "OPTIONS")
                .allowCredentials(true);
    }
}

 

Gateway 라우팅 등록

게이트웨이에 들어오는 요청을 라우팅해 주도록 하자

게이트웨이는 80 포트, product 모듈은 8080 포트에, review 모듈은 9091 포트를 사용하고 있다.

게이트웨이 내 경로가 /product, /review 로 시작하는 요청이 들어올 경우 해당 요청을 8080/product/**, 9092/review/** 로 라우팅해주자

yml에 작성해 등록시키는 방법과 직접 빈으로 등록하는 두 가지 방식을 사용한다.

1. 설정파일(applicaion.yml) 내 작성

spring:
  cloud:
    gateway:
      routes:
        - id: product
          uri: http://localhost:8080
          predicates:
            - Path=/product/**
        - id: review
          uri: http://localhost:9092
          predicates:
            - Path=/review/**

2. 직접 빈으로 등록

@Configuration
public class GatewayConfig {
    @Bean
    public RouteLocator productRoute(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("product",
                        r -> r.path("/product/**")
                                .uri("http://localhost:8080"))
                .build();
    }

    @Bean
    public RouteLocator reviewRoute(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("review",
                        r -> r.path("/review/**")
                                .uri("http://localhost:9092"))
                .build();
    }
}

개인적으로는 CORS 같은 글로벌 설정은 yml에 기입하고,
라우팅 같은 구체적인 설정 작성이 필요한 경우에는 빈으로 등록하는 것이 좋을 것 같다.

참고

https://docs.spring.io/spring-cloud-gateway/reference/index.html