๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
  • ์žฅ์›์ต ๊ธฐ์ˆ ๋ธ”๋กœ๊ทธ
๐Ÿ’Š Java & Kotlin & Spring/- spring framework +

Spring Cloud Gateway ์—์„œ Built-in Route๋กœ Predicates์™€ Filter ์กฐ์ž‘ํ•˜๊ธฐ

by Wonit 2021. 4. 24.

ํ•ด๋‹น ๊ธ€์€ SGC๋ฅผ ์ด์šฉํ•ด API Gateway๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ  Eureka Server ๋ฅผ ์ด์šฉํ•ด Load Balancing ํ•˜๊ธฐ) ์— ์˜์กดํ•˜๋Š” ๊ธ€์ž…๋‹ˆ๋‹ค. ์‹ค์Šต ํ™˜๊ฒฝ์„ ๋”ฐ๋ผํ•˜์‹œ๋ ค๋ฉด ์ด์ „ ๊ธ€์„ ํ™•์ธํ•˜์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๋ชฉ์ฐจ

  • Spring Cloud Gateway
    • Routes, Predicates, Filters
  • Route Predicates
    • Built-in Factories ์‚ฌ์šฉํ•˜๊ธฐ
      • After
      • Cookie
      • Method
      • Path
  • Route Filters
    • AddRequestHeader, AddResponseHeader
    • AddRequestParameter
    • RewritePath

Spring Cloud Gateway ์—์„œ๋Š” Predicates์™€ Filter๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ application.yml ์„ ์ด์šฉํ•œ shortcut ๋ฐฉ๋ฒ•๊ณผ java code๋ฅผ ์ด์šฉํ•œ ๋ฐฉ๋ฒ•์ด ์กด์žฌํ•œ๋‹ค.

 

์˜ค๋Š˜์€ application.yml์„ ์ด์šฉํ•œ shorcut ๋ฐฉ๋ฒ•์„ ์ด์šฉํ•ด์„œ predicate์™€ filter๋ฅผ ์กฐ์ž‘ํ•ด๋ณด๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๋ ค ํ•œ๋‹ค.

Spring Cloud Gateway

์ง€๋‚œ ์‹œ๊ฐ„ ์•Œ์•„๋ณด์•˜๋˜ Spring Cloud Gateway, SCG์— ๋Œ€ํ•ด์„œ ๊ฐ„๋žตํ•˜๊ฒŒ ๋‹ค์‹œ ์งš์–ด๋ณด์ž.

 

 

Spring Cloud Gateway๋Š” API Gateway ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” Spring Cloud์˜ ๊ณต์‹ ํ”„๋กœ์ ํŠธ์ด๋‹ค.

 

Netflix Zuul ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜์ง€๋งŒ ๋น„๋™๊ธฐ ์ˆ˜ํ–‰์„ ์œ„ํ•ด Spring WebFlux ๋กœ Netty ์œ„์—์„œ ๋Œ์•„๊ฐ€๋Š” Spring boot application์ด๋‹ค.

 

์šฐ๋ฆฌ๋Š” ๋‹ค์–‘ํ•œ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๋“ค์„ Gateway์— ์—ฐ๊ฒฐ์‹œ์ผœ ๋ชจ๋“  ์„œ๋น„์Šค๋“ค์˜ ์ง„์ž…์ ์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ณ  Gateway ๋‚ด์—์„œ HTTP ์š”์ฒญ์— ๋Œ€ํ•œ ๋‹ค์–‘ํ•œ ์กฐ์ž‘์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

Routes, Predicates, Filters

Spring Cloud Gateway์—์„œ๋Š” ์ด 3๊ฐ€์ง€ ๊ฐœ๋…์ด ๊ฐ€์žฅ ์ค‘์š”ํ•˜๋‹ค.

  1. Routes
  2. Predicates
  3. Filters

Spring Cloud Gateway ๋กœ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด Gateway Handler Mapping ์ด ๋™์ž‘ํ•œ๋‹ค.

 

Gateway Handler Mapping ์—์„œ๋Š” ๋‚ด๋ถ€์— Predicates(์กฐ๊ฑด)์ด ๋งž๋‹ค๋ฉด Filter๋“ค์„ ๊ฑฐ์น˜๊ฒŒ ํ•˜๊ณ  Route ํ•œ๋‹ค.

 

 

์šฐ๋ฆฌ๋Š” ์ด 3๊ฐ€์ง€ ๊ตฌ์„ฑ ์š”์†Œ๋“ค์„ application.yml ์—์„œ ์ง€์ •ํ•˜๊ณ  ์žˆ๋‹ค

 

spring:
  application:
    name: gateway-service

  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/user/**

        - id: order-service
          uri: lb://ORDER-SERVICE
          predicates:
            - Path=/order/**

ํ•ด๋‹น ๊ธ€์€ SGC๋ฅผ ์ด์šฉํ•ด API Gateway๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ  Eureka Server ๋ฅผ ์ด์šฉํ•ด Load Balancing ํ•˜๊ธฐ) ์— ์˜์กดํ•˜๋Š” ๊ธ€์ž…๋‹ˆ๋‹ค. ์‹ค์Šต ํ™˜๊ฒฝ์„ ๋”ฐ๋ผํ•˜์‹œ๋ ค๋ฉด ์ด์ „ ๊ธ€์„ ํ™•์ธํ•˜์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค.

 


yml shortcut์œผ๋กœ Route Predicate ์กฐ์ž‘ํ•˜๊ธฐ

์•ž์„œ ์ด์•ผ๊ธฐํ–ˆ๋“ฏ Spring Cloud Gateway๋Š” HandlerMapping ์—์„œ Predicate๊ฐ€ ์ผ์น˜ํ•  ๋•Œ๋งŒ ๋ผ์šฐํŒ…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.


Spring Cloud Gateway ๋Š” ๋งŽ์€ built-in Predicate Factory ๋“ค์„ ์ œ๊ณตํ•œ๋‹ค.

  • After
  • Cookie
  • Method
  • Path

After & Before & Between

After & Before & Between๋Š” ์‹œ๊ฐ„๊ณผ ๊ด€๋ จ๋œ Predicates๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

 

๋ง ๊ทธ๋Œ€๋กœ After๋Š” ํŠน์ • ์‹œ๊ฐ„ ์ดํ›„, Before๋Š” ํŠน์ • ์‹œ๊ฐ„ ์ด์ „, Between์€ ํŠน์ • ์‹œ๊ฐ„ ์‚ฌ์ด๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

 

application.yml ๋กœ ๊ฐ€์„œ predicates ์•„๋ž˜์— After๊ณผ Before ๊ทธ๋ฆฌ๊ณ  Between์„ ๊ฐ๊ฐ ์ง€์ •ํ•ด๋ณด์ž.

 

spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/user/**
            - After=2017-01-20T17:42:47.789-07:00

        - id: order-service
          uri: lb://ORDER-SERVICE
          predicates:
            - Path=/order/**
            - Before=2017-01-20T17:42:47.789-07:00

 

์œ„์˜ ์กฐ๊ฑด์„ ๋ณด๋ฉด user-service๋Š” After ๋กœ 2017๋…„ ์ดํ›„ ์š”์ฒญ๋งŒ ๋ฐ›๊ณ ์žˆ๊ณ  order-service๋Š” 2017๋…„ ์ด์ „ ์š”์ฒญ๋งŒ ๋ฐ›๊ณ ์žˆ๋‹ค.

 

์˜ˆ์ƒํ•ด๋ณด์ž

  • ํ˜„์žฌ 2021๋…„๋„๋Š” 2017๋…„ ์ดํ›„(After) ์ด๋ฏ€๋กœ User-Service๋Š” ์ž˜ ๋™์ž‘ํ•  ๊ฒƒ์ด๋‹ค.
  • ํ˜„์žฌ 2021๋…„๋„๋Š” 2017๋…„ ์ด์ „(Before) ์ด ์•„๋‹ˆ๋ฏ€๋กœ Order-Service๋Š” ๋™์ž‘ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค.

 

Postman ์œผ๋กœ ํ…Œ์ŠคํŠธํ•˜๋ฉด?

 

 

์šฐ๋ฆฌ์˜ ์˜ˆ์ƒ๋Œ€๋กœ ๋‚˜์˜จ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

Between ๋˜ํ•œ ๋น„์Šทํ•œ ๋งฅ๋ฝ์œผ๋กœ ๋™์ž‘ํ•˜๋Š”๋ฐ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•์‹์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.


- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

Cookie

Cookie Predicate ๋Š” ์š”์ฒญ์— Cookie ๊ฐ’์ด ์ง€์ •๋œ ์ •๊ทœํ‘œํ˜„์‹์„ ๋งŒ์กฑํ•˜๋Š”์ง€ ์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

 

predicates:
  - Cookie=name, regexp

 

ํ˜•ํƒœ๋กœ ์‚ฌ์šฉ๋˜๋Š”๋ฐ, ์ง์ ‘ ์‚ฌ์šฉํ•ด๋ณด์ž.

 

spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/user/**
            - Cookie=valid, kakao

        - id: order-service
          uri: lb://ORDER-SERVICE
          predicates:
            - Path=/order/**
            - Cookie=valid, naver

์˜ˆ์ƒํ•ด๋ณด์ž

  • User-Service ์˜ valid ํ•„๋“œ์— kakao ๋ฅผ ๋„ฃ์œผ๋ฉด ์ž˜ ๋™์ž‘ํ•  ๊ฒƒ์ด๋‹ค.
  • Order-Service ์˜ valid ํ•„๋“œ์— kakao ๋ฅผ ๋„ฃ์œผ๋ฉด ๋™์ž‘ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค.

Method

 

Method Predicates ๋Š” HTTP Method ๊ฐ€ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

 

spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/user/**
            - Method=GET

        - id: order-service
          uri: lb://ORDER-SERVICE
          predicates:
            - Path=/order/**
            - Method=POST

์˜ˆ์ƒํ•ด๋ณด์ž

  • User-Service ๋กœ GET ์š”์ฒญ ์„ ๋ณด๋‚ด๋ฉด ์ž˜ ๋™์ž‘ํ•  ๊ฒƒ์ด๋‹ค.
  • Order-Service ์˜ GET ์š”์ฒญ ์„ ๋ณด๋‚ด๋ฉด ๋™์ž‘ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค.

yml shortcut์œผ๋กœ Route Filters ์กฐ์ž‘ํ•˜๊ธฐ

Route Filter๋Š” Gateway๋กœ ๋“ค์–ด์˜ค๋Š” HTTP Request๋‚˜ ๋‚˜๊ฐ€๋Š” Response ๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.


Spring Cloud Gateway ๋Š” ๋งŽ์€ built-in GatewayFilter Factory ๋“ค์„ ์ œ๊ณตํ•œ๋‹ค.

  • AddRequestHeader, AddResponseHeader
  • AddRequestParameter
  • RewritePath

์ด๋Ÿฐ Filter ๊ธฐ๋Šฅ์œผ๋กœ ์ธ์ฆ๊ณผ ์ธ๊ฐ€๋ฅผ ์ปค๋ฒ„ํ•  ์ˆ˜ ์žˆ๊ณ  ๋‹ค์Œ์— ๋ฐฐ์šธ Circuit Breaker ๋„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

AddRequestHeader, AddResponseHeader

AddRequestHeader๊ณผ AddResponseHader๋Š” name๊ณผ value ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›๋Š”๋‹ค.

 

spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/user/**
          filters:
            - AddRequestHeader=token, 123456
            - AddResponseHeader=authenticated, yes

 

๊ทธ๋ฆฌ๊ณ  User-Service๋กœ ๋Œ์•„๊ฐ€์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•ด๋ณด์ž.

 

@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class UserServiceApplication {

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

    @GetMapping("/user/info")
    public String info(@Value("${server.port}") String port) {
        return "User ์„œ๋น„์Šค์˜ ๊ธฐ๋ณธ ๋™์ž‘ Port: {" + port + "}";
    }

    @GetMapping("/user/auth")
    public String auth(@RequestHeader(value = "token") String token) {
        return "token is " + token;
    }

}

 

์˜ˆ์ƒํ•ด๋ณด์ž

  • HTTP Request ์— token = 123456 ์ด๋ผ๋Š” Request Header๊ฐ€ ์ถ”๊ฐ€๋  ๊ฒƒ์ด๋‹ค.
  • ์‘๋‹ต ํ—ค๋”์— authenticated = yes ๊ฐ€ ์ถœ๋ ฅ๋  ๊ฒƒ์ด๋‹ค.

์ด์™€ ๋”๋ถˆ์–ด์„œ RemoveRequestHeader๊ณผ RemoveResponseHeader ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.


๋˜ํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, AddRequestParameter ๋กœ ์ถ”๊ฐ€ํ•  ์ˆ˜์žˆ๋‹ค.

 

spring:
  cloud:
    gateway:
      routes:
        - id: add_request_parameter_route
          uri: https://example.org
          filters:
            - AddRequestParameter=red, blue

RewritePath

RewritePath๋Š” ์ •๊ทœํ‘œํ˜„์‹์„ ์ด์šฉํ•ด์„œ replacement ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ด ๊ธฐ๋Šฅ์€ ์กฐ๊ธˆ ์ค‘์š”ํ•œ๋ฐ, ์šฐ๋ฆฌ๊ฐ€ ๊ตฌ์„ฑํ•œ ์„œ๋น„์Šค์—๋Š” ์•„์ฃผ ์‚ฌ์†Œํ•œ ๋ฌธ์ œ๊ฐ€ ์กด์žฌํ•œ๋‹ค.

 

spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/user/**

        - id: order-service
          uri: lb://ORDER-SERVICE
          predicates:
            - Path=/order/**

 

predicates ์—์„œ /user/** ๋กœ ์ง€์ •ํ•˜๊ณ  ์žˆ๊ณ  ์šฐ๋ฆฌ์˜ User-Service ์—์„œ๋„ /user/info ๋กœ ๋ฐ›๊ณ  ์žˆ๋‹ค.

๊ทธ๋Ÿผ ์ด๋Ÿฐ ์ƒ๊ฐ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์–ด์ฐจํ”ผ User-Service ์ž…์žฅ์—์„œ๋Š” ๋“ค์–ด์˜ค๋Š” ๋ชจ๋“  ์š”์ฒญ์ด /user ๋กœ ์‹œ์ž‘ํ•  ๊ฑธ ์•„๋Š”๋ฐ, User-Service ์•ˆ์—์„œ๋ผ๋„ /user ๋ผ๋Š” prefix๋ฅผ ๋นผ๋ฉด ์•ˆ๋ ๊นŒ?

 

์ถฉ๋ถ„ํžˆ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

์ง€๋‚œ ์‹œ๊ฐ„ RewritePath ๋ฅผ ์ด์šฉํ•  ๊ฒƒ์ด๋ผ ์˜ˆ๊ณ ํ•œ ๊ฒƒ์ด ๋ฐ”๋กœ ์ด๊ฑฐ๋‹ค.

 

๋‹ค์Œ๊ณผ ๊ฐ™์ด RewritePath ํ•„ํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ์ž.

 

spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/user/**
          filters:
            - RewritePath=/user/?(?<segment>.*), /$\{segment}

        - id: order-service
          uri: lb://ORDER-SERVICE
          predicates:
            - Path=/order/**
          filters:
            - RewritePath=/order/?(?<segment>.*), /$\{segment}

๊ทธ๋ฆฌ๊ณ  ๊ฐ๊ฐ์˜ User, Order ์„œ๋น„์Šค๋กœ ๋Œ์•„๊ฐ€์„œ RequestMapping ๋ถ€๋ถ„์— /user, /order์„ ๋นผ๊ณ  ์š”์ฒญ์„ ๋ณด๋‚ด๋ณด์ž.

@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class UserServiceApplication {

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

    @GetMapping("/info")
    public String info(@Value("${server.port}") String port) {
        return "User ์„œ๋น„์Šค์˜ ๊ธฐ๋ณธ ๋™์ž‘ Port: {" + port + "}";
    }
}

@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class OrderServiceApplication {

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

    @GetMapping("/info")
    public String info(@Value("${server.port}") String port) {
        return "User ์„œ๋น„์Šค์˜ ๊ธฐ๋ณธ ๋™์ž‘ Port: {" + port + "}";
    }
}

๋Œ€์‹  ์š”์ฒญ์€ /user, /order ๋กœ ๋ณด๋‚ด์•ผ ํ•œ๋‹ค! ๋‹จ์ง€ ๋‚ด๋ถ€์ ์œผ๋กœ RequestMapping ์˜ ์ค‘๋ณต๋œ ๋ถ€๋ถ„์„ Replacement ํ•œ ๊ฒƒ ๋ฟ์ด๋‹ค.


์ด๋ ‡๊ฒŒ ์˜ค๋Š˜์€ Spring Cloud Gateway ์˜ Built-in Routes ๋ฅผ ์ด์šฉํ–ˆ๋‹ค.
๋‹ค์Œ ์‹œ๊ฐ„์—๋Š” Global Filter๊ณผ Custom Filter๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณผ ๊ฒƒ์ด๋‹ค.

๋Œ“๊ธ€