본문 바로가기

Study Information Technology

Spring Cloud Gateway와 Spring Boot를 이용한 API Gateway 패턴 구현

728x90
반응형

Spring Cloud Gateway와 Spring Boot를 이용한 API Gateway 패턴 구현

Overview

API Gateway 패턴은 마이크로서비스 아키텍처에서 중요한 역할을 하는 디자인 패턴입니다. 이 패턴은 클라이언트와 여러 마이크로서비스 간의 중개자로서, 클라이언트 요청을 적절한 서비스로 라우팅하는 역할을 합니다. Spring Cloud Gateway와 Spring Boot를 이용하여 이 패턴을 구현하는 방법을 자세히 설명하겠습니다. Spring Cloud Gateway는 고성능의 API 게이트웨이로, 동적 라우팅, 필터링, 리밸런싱 기능을 제공하며, Spring Boot와 함께 사용하여 빠르게 구축할 수 있습니다.

기본 설정

1. Spring Boot 프로젝트 생성

Spring Boot 프로젝트를 생성하는 방법은 여러 가지가 있지만, 가장 간편한 방법은 Spring Initializr를 사용하는 것입니다.

  1. Spring Initializr에 접속하여 새로운 프로젝트를 생성합니다.
  2. Project: Maven Project 또는 Gradle Project를 선택합니다.
  3. Language: Java를 선택합니다.
  4. Spring Boot: 최신 버전을 선택합니다.
  5. Project Metadata: Group, Artifact, Name, Description 등을 입력합니다.
  6. Dependencies: 'Spring Cloud Gateway', 'Spring Boot DevTools', 'Eureka Discovery Client'를 선택합니다.
  7. Generate 버튼을 클릭하여 ZIP 파일을 다운로드하고, 이를 풀어 IntelliJ IDEA 또는 Eclipse와 같은 IDE로 엽니다.

2. Maven 또는 Gradle 설정

프로젝트를 생성하면, pom.xml (Maven) 또는 build.gradle (Gradle) 파일이 생성됩니다. 의존성을 추가해야 합니다.

Maven 설정

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>

Gradle 설정

implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'org.springframework.cloud:spring-cloud-starter-eureka'

그리고 pom.xml이나 build.gradle 파일에 Spring Cloud 버전을 지정해주어야 합니다. 예를 들어, Spring Cloud 2024.0.0을 사용할 수 있습니다.

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>2024.0.0</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:2024.0.0"
}
}

Spring Cloud Gateway 설정

1. application.yml 설정

src/main/resources/application.yml 파일을 수정하여 Spring Cloud Gateway의 기본 설정을 합니다. 다음은 기본적인 설정 예제입니다.

spring:
application:
name: api-gateway
cloud:
gateway:
routes:
- id: service1
uri: lb://SERVICE1
predicates:
- Path=/service1/**
filters:
- StripPrefix=1
- id: service2
uri: lb://SERVICE2
predicates:
- Path=/service2/**
filters:
- StripPrefix=1
discovery:
client:
simple:
enabled: true

이 설정 파일에서는 두 개의 서비스(SERVICE1, SERVICE2)를 라우팅하는 규칙을 정의하고 있습니다. lb:// 접두사는 로드 밸런서를 통해 서비스를 찾는다는 것을 의미합니다. StripPrefix=1 필터는 URL에서 접두사를 제거하여 서비스를 호출할 때 사용됩니다.

2. 애플리케이션 클래스

애플리케이션의 메인 클래스를 작성하여 Spring Boot 애플리케이션을 시작합니다. 기본적인 ApiGatewayApplication 클래스는 다음과 같습니다.

package com.example.apigateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ApiGatewayApplication {

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

서비스 등록과 디스커버리

Spring Cloud Gateway는 서비스 등록과 디스커버리 기능을 통해 동적으로 서비스를 찾습니다. application.yml 파일에 eureka 디스커버리 클라이언트를 설정하여 Eureka 서버와 통신할 수 있습니다.

1. Eureka 서버 설정

Eureka 서버를 설정하려면 Spring Boot로 별도의 Eureka 서버를 구성해야 합니다. spring-cloud-starter-eureka-server 의존성을 추가하고, @EnableEurekaServer 어노테이션을 사용하여 서버를 활성화합니다.

Maven 설정

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>

Gradle 설정

implementation 'org.springframework.cloud:spring-cloud-starter-eureka-server'

Eureka 서버 애플리케이션

package com.example.eurekaserver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

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

2. 서비스 등록

각 마이크로서비스는 Eureka 서버에 등록됩니다. 서비스 애플리케이션에 spring-cloud-starter-eureka 의존성을 추가하고, application.yml 파일에 Eureka 서버 주소를 설정합니다.

서비스 애플리케이션 설정

spring:
application:
name: service1
cloud:
discovery:
client:
service-url:
defaultZone: http://localhost:8761/eureka/

필터와 라우팅

Spring Cloud Gateway는 요청과 응답을 처리하는 다양한 필터를 지원합니다. 필터는 요청을 수정하거나, 응답을 변형하는 데 사용됩니다.

1. 기본 필터 설정

application.yml 파일에서 filters 항목을 사용하여 필터를 설정할 수 있습니다.

spring:
cloud:
gateway:
routes:
- id: service1
uri: lb://SERVICE1
predicates:
- Path=/service1/**
filters:
- StripPrefix=1
- AddRequestHeader=MyHeader, MyHeaderValue

이 설정에서는 AddRequestHeader 필터를 사용하여 요청에 헤더를 추가합니다.

2. 사용자 정의 필터

Spring Cloud Gateway에서는 Java 코드를 사용하여 사용자 정의 필터를 작성할 수도 있습니다.

사용자 정의 필터 작성

package com.example.apigateway.filters;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class CustomGatewayFilter implements GatewayFilter {

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 요청을 필터링하는 로직을 구현합니다.
System.out.println("Custom Filter: " + exchange.getRequest().getPath());
return chain.filter(exchange);
}
}

이 필터는 요청 경로를 콘솔에 출력합니다. 필터를 사용하려면 라우트 설정에서 필터를 참조해야 합니다.

spring:
cloud:
gateway:
routes:
- id: service1
uri: lb://SERVICE1
predicates:
- Path=/service1/**
filters:
- StripPrefix=1
- name: CustomGatewayFilter

에러 처리

Spring Cloud Gateway는 요청 처리 중 발생할 수 있는 다양한 에러를 관리할 수 있습니다. 기본적으로 4xx 및 5xx 에러를 처리할 수 있는 핸들러를 제공하며, 필요에 따라 커스터마이징할 수 있습니다.

1. 기본 에러 페이지 설정

기본적인 에러 페이지를 설정하려면 application.yml 파일에서 spring.cloud.gatewaydefault-filters를 사용합니다.

spring:
cloud:
gateway:
default-filters:
- name: AddResponseHeader
args:
name: X-Response-Status
value: 500

이 설정은 모든 응답에 X-Response-Status 헤더를 추가합니다.

2. 커스터마이즈된 에러 핸들링

에러 처리 핸들러를 커스터마이즈하려면, @ControllerAdvice를 사용하여 전역적으로 예외를 처리할 수 있습니다.

package com.example.apigateway.exception;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation
728x90
반응형