본문 바로가기

개발(합니다)/Java&Spring

[spring boot 설정하기-20] spring cloud gateway(1) 설정 및 테스트 소스

반응형

 

1. 개요

Spring Cloud Gateway(SCG)

spring cloud gateway(scg)는 API Gateway 중 하나로 API 라우팅 및 보안, 모니터링/매트릭 등의 기능을 제공합니다.

  • 유입되는 모든 요청과 응답에 대한 인증과 보안을 적용
  • URI에 따라 서비스 엔드포인트를 다르게 하는 동적 라우팅이 가능 : 도메인을 유지하고 레거시를 신규 시스템으로 교체
  • 모든 트래픽에 대한 모니터링 시스템 구성 : 로깅
  • 동적 라우팅이 가능하여 신규 스팩을 서비스 일부에만 적용하거나 점진적으로 확장하여 테스트 가능
  • Spring Cloud LoadBalancer가 포함되어 있다.

Spring Cloud Zuul과의 차이점

Zuul은 zuul1과 zuul2로 구분됩니다.

  • zuul1는 서블릿 프레임워크 기반으로 동기와 블로킹 방식으로 서비스
  • zuul2는 비동기와 논블로킹 방식을 지원하도록 업데이트

zuul이 Spring 생태계의 취지와 맞지 않아
Spring Gateway를 WebFlux와 Reactor 프로젝트를 기반으로 새로 만들게 되었습니다.

Spring Cloud Gateway도 zuul처럼 비동기와 논블로킹 방식으로 개발되었고 성능은 더 우수하다는 분석 글들이 있습니다.

  • Spring cloud Gateway는 Netty 런타임 기반으로 동작

용어

명칭 설명
라우트(Route) 목적지 URI, 조건자 목록과 필터의 목록을 식별하기 위한 고유 ID로 구성되며
모든 조건자가 충족되어야 매칭
조건자(Predicates) 각 요청을 처리하기 전에 실행되는 로직, 헤더와 입력된 값 등 다양한 HTTP 요청이 정의 된 기준에 맞는지를 확인
필터(Filter) HTTP 요청이나 HTTP 응답을 수정하고 다운스트림 요청을 보내기전이나 후에 수정할 수 있으며 특정 라우트에 한정

관련 정보는 아래 사이트에서 확인해 볼수 있습니다.

https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-starter

2. 설정 및 팁

해당 팁은 다음 포스팅과 함께 보시거나 다음 포스팅을 보고 보시면 더욱 좋습니다.

2-1. Gateway Route 노출

gateway-server의 actuator를 이용하면 gateway에 대한 정보를 확인할 수 있습니다.

management:
    endpoints:
        web:
            exposure:
                include:
                    - "gateway"
    endpoint:
        gateway:
            enabled: true

위와 같이 설정 후 http://localhost:9999/actuator/gateway/routes를 조회하면 현재 routes 할 수 있는 정보가 나타납니다.

2-2. HTTP Timeout 설정

  • connect-timeout 밀리초 단위
  • reponse-timeout Duration 단위
spring:
  cloud:
    gateway:
      httpclient:
        connect-timeout: 1000
        response-timeout: 10s

2-3. route 설정

  • id : 라우트의 고유 식별자
  • uri : 라우터의 주소
  • predicates : 라우터의 조건으로 /user/** 시작하는 요청을 해당 라우터로 요청
  • filters : 라우터의 필터이고 RewritePaths는 강제로 Path를 다시 작성
spring:
  cloud:
    gateway:
      default-filters:
        - name: GlobalFilter
          args:
            baseMessage: Spring Cloud Gateway GlobalFilter
            preLogger: true
            postLogger: true
      routes:
        - id: user-service
          uri: http://localhost:6666
          predicates:
            - Path=/user/**
          filters:
            - name: GlobalFilter
              ages:
                baseMessage: Spring Cloud Gateway GlobalFilter
                preLogger: true
                postLogger: true
#            - RewritePath=/order/(?<path>.*),/$\{path}

        - id: cafe-service
          uri: http://localhost:7777
          predicates:
            - Path=/cafe/**
          filters:
            - name: GlobalFilter
              args:
                baseMessage: Spring Cloud Gateway GlobalFilter
                preLogger: true
                postLogger: true
#            - RewritePath=/cafe/(?<path>.*),/$\{path}

2-4. Predicates 설정

조건으로 설정한 라우터에 라우팅 될 조건을 설정할 수 있습니다.

설정 새로고침 테스트는 intellij .http로 했으며 해당 gateway-server에서 실행합니다.
cloud-config의 전파로 자동 갱신되어야 하지만
정상적으로 동작하지 않아 gateway에 있는 actuator로 실행합니다.
POST http://localhost:9999/actuator/refresh

After

특정 날짜 이후에 호출이 가능하도록 하는 설정입니다.
현재 날짜가 지정한 날짜보다 이후여야만 API를 호출할 수 있습니다.

spring:
  cloud:
    gateway:
      default-filters:
        - name: GlobalFilter
          args:
            baseMessage: Spring Cloud Gateway GlobalFilter
            preLogger: true
            postLogger: true
      routes:
        - id: user-service
          uri: http://localhost:6666
          predicates:
            - Path=/user/**
            - After=2021-05-15T20:20:20.126+09:00[Asia/Seoul]
        - id: cafe-service
          uri: http://localhost:7777
          predicates:
            - Path=/cafe/**
            - After=2021-05-21T20:20:20.126+09:00[Asia/Seoul]

Befre

특정 날짜 이전에 호출이 가능하도록 하는 설정입니다.
현재 날짜가 지정한 날짜보다 이전이여야만 API를 호출할 수 있습니다.

spring:
  cloud:
    gateway:
      default-filters:
        - name: GlobalFilter
          args:
            baseMessage: Spring Cloud Gateway GlobalFilter
            preLogger: true
            postLogger: true
      routes:
        - id: user-service
          uri: http://localhost:6666
          predicates:
            - Path=/user/**
            # - After=2021-05-15T20:20:20.126+09:00[Asia/Seoul]
            - Before=2021-05-15T20:20:20.126+09:00[Asia/Seoul]
          filters:
            - name: GlobalFilter
              ages:
                baseMessage: Spring Cloud Gateway GlobalFilter
                preLogger: true
                postLogger: true

        - id: cafe-service
          uri: http://localhost:7777
          predicates:
            - Path=/cafe/**
            # - After=2021-05-21T20:20:20.126+09:00[Asia/Seoul]
            - Before=2021-05-21T20:20:20.126+09:00[Asia/Seoul]

Between

특정 날짜 사이에서만 호출이 가능하도록 하는 설정입니다.
현재 날짜가 지정한 날짜 사이에 있어야만 API를 호출할 수 있습니다.

spring:
  cloud:
    gateway:
      default-filters:
        - name: GlobalFilter
          args:
            baseMessage: Spring Cloud Gateway GlobalFilter
            preLogger: true
            postLogger: true
      routes:
        - id: user-service
          uri: http://localhost:6666
          predicates:
            - Path=/user/**
            # - After=2021-05-15T20:20:20.126+09:00[Asia/Seoul]
            # - Before=2021-05-15T20:20:20.126+09:00[Asia/Seoul]
            - Between=2021-05-15T20:20:20.126+09:00[Asia/Seoul], 2021-05-15T21:21:21.126+09:00[Asia/Seoul]
          filters:
            - name: GlobalFilter
              ages:
                baseMessage: Spring Cloud Gateway GlobalFilter
                preLogger: true
                postLogger: true
#            - RewritePath=/order/(?<path>.*),/$\{path}

        - id: cafe-service
          uri: http://localhost:7777
          predicates:
            - Path=/cafe/**
            # - After=2021-05-21T20:20:20.126+09:00[Asia/Seoul]
            # - Before=2021-05-21T20:20:20.126+09:00[Asia/Seoul]
            - Between=2021-05-05T20:20:20.126+09:00[Asia/Seoul], 2021-05-30T20:20:20.126+09:00[Asia/Seoul]
          filters:
            - name: GlobalFilter
              args:
                baseMessage: Spring Cloud Gateway GlobalFilter
                preLogger: true
                postLogger: true
#            - RewritePath=/cafe/(?<path>.*),/$\{path}

Weight

group, weight를 기반으로 그룹별로 가중치를 계산하고 라우팅을 분배합니다.
2개의 같은 서버에 대한 트래픽 분배를 위한 가중치를 설정합니다.

spring:
  cloud:
    gateway:
      default-filters:
        - name: GlobalFilter
          args:
            baseMessage: Spring Cloud Gateway GlobalFilter
            preLogger: true
            postLogger: true
      routes:
        - id: user-service-high
          uri: http://localhost:6666
          predicates:
            - Path=/user/**
            # - After=2021-05-15T20:20:20.126+09:00[Asia/Seoul]
            # - Before=2021-05-15T20:20:20.126+09:00[Asia/Seoul]
            - Between=2021-05-15T20:20:20.126+09:00[Asia/Seoul], 2021-05-15T21:21:21.126+09:00[Asia/Seoul]
            - Weight=group-order, 9
          filters:
            - name: GlobalFilter
              ages:
                baseMessage: Spring Cloud Gateway GlobalFilter
                preLogger: true
                postLogger: true
#            - RewritePath=/order/(?<path>.*),/$\{path}
        - id: user-service-low
          uri: http://localhost:6665
          predicates:
            - Path=/user/**
            # - After=2021-05-15T20:20:20.126+09:00[Asia/Seoul]
            # - Before=2021-05-15T20:20:20.126+09:00[Asia/Seoul]
            - Between=2021-05-15T20:20:20.126+09:00[Asia/Seoul], 2021-05-15T21:21:21.126+09:00[Asia/Seoul]
            - Weight=group-order, 1
          filters:
            - name: GlobalFilter
              ages:
                baseMessage: Spring Cloud Gateway GlobalFilter
                preLogger: true
                postLogger: true
#            - RewritePath=/order/(?<path>.*),/$\{path}

2-5. Filter 설정

HTTP Request, Response에 대한 수정을하거나 특정 라우터에서 동작합니다.

RewritePath

HTTP Request를 수정하여 특정 Server로 전달하고 정규표현식을 사용할 수 있습니다.

        - id: cafe-service
          uri: http://localhost:7777
          predicates:
            - Path=/cafe/**
            # - After=2021-05-21T20:20:20.126+09:00[Asia/Seoul]
            # - Before=2021-05-21T20:20:20.126+09:00[Asia/Seoul]
            - Between=2021-05-05T20:20:20.126+09:00[Asia/Seoul], 2021-05-30T20:20:20.126+09:00[Asia/Seoul]
          filters:
            - name: GlobalFilter
              args:
                baseMessage: Spring Cloud Gateway GlobalFilter
                preLogger: true
                postLogger: true
            - RewritePath=/cafe/(?<path>.*),/$\{path}

Retry

name 설명 기본값
retries 재시도 횟수 3
statuses 재시도해야하는 HTTP 상태 코드 -
series 재시도해야하는 HTTP 상태 코드 시리즈 5XX
methods 재시도해야 하는 HTTP 메서드 GET
exceptions 재시도 해야하는 Exception IOException, TimeoutException
backoff 재시도하는 시간텀 지정 firstBackoff * (factor ^ n) n번 반복 false
        - id: cafe-service
          uri: http://localhost:7777
          predicates:
            - Path=/cafe/**
            # - After=2021-05-21T20:20:20.126+09:00[Asia/Seoul]
            # - Before=2021-05-21T20:20:20.126+09:00[Asia/Seoul]
            - Between=2021-05-05T20:20:20.126+09:00[Asia/Seoul], 2021-05-30T20:20:20.126+09:00[Asia/Seoul]
          filters:
            - name: GlobalFilter
              args:
                baseMessage: Spring Cloud Gateway GlobalFilter
                preLogger: true
                postLogger: true
            - RewritePath=/cafe/(?<path>.*),/$\{path}
            - name: Retry
              args:
                retries: 3
                statuses: INTERNAL_SERVER_ERROR
                methods: GET
                backoff:
                  firstBackoff: 1000ms
                  maxBackoff: 6000ms
                  factor: 2
반응형