ํด๋น ๊ธ์ SGC๋ฅผ ์ด์ฉํด API Gateway๋ฅผ ๊ตฌ์ฑํ๊ณ Eureka Server ๋ฅผ ์ด์ฉํด Load Balancing ํ๊ธฐ) ์ ์์กดํ๋ ๊ธ์ ๋๋ค. ์ค์ต ํ๊ฒฝ์ ๋ฐ๋ผํ์๋ ค๋ฉด ์ด์ ๊ธ์ ํ์ธํ์๊ธธ ๋ฐ๋๋๋ค.
๋ชฉ์ฐจ
- Spring Cloud Gateway
- Routes, Predicates, Filters
- Route Predicates
- Built-in Factories ์ฌ์ฉํ๊ธฐ
- After
- Cookie
- Method
- Path
- Built-in Factories ์ฌ์ฉํ๊ธฐ
- 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๊ฐ์ง ๊ฐ๋ ์ด ๊ฐ์ฅ ์ค์ํ๋ค.
- Routes
- Predicates
- 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๋ฅผ ๊ตฌ์ฑํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์์๋ณผ ๊ฒ์ด๋ค.
๋๊ธ