Spring Cloud Api Gateway(Filter)
๐ฟ APi Gateway ์ฃผ์ ๊ธฐ๋ฅ
- ์ธ์ฆ ๋ฐ ์ธ๊ฐ(Authentication and Authorization)
์ธ์ฆ์ ๊ด๋ฆฌ๋, ์ธ์ฆ, SSL, ํ๋กํ ์ฝ ๋ณํ๊ณผ ๊ฐ์ ๊ธฐ๋ฅ๋ค์ API Gateway์์ ์คํ๋ก๋ ํจ์ผ๋ก, ๊ฐ๊ฐ์ ์๋น์ค์ ๋ถ๋ด์ ์ค์ด๊ณ , ์๋น์ค์ ๊ด๋ฆฌ ๋ฐ ์ ๊ทธ๋ ์ด๋๋ฅผ ๋ณด๋ค ์ฝ๊ฒ ์ฒ๋ฆฌ
Authentication(์ธ์ฆ)๊ณผ Authorization(์ธ๊ฐ)์ ์ฐจ์ด
Authentication์ ์ ์ ๊ฐ ๋๊ตฌ์ธ์ง ํ์ธํ๋ ์ ์ฐจ(A๋ผ๊ณ ํ๋ฉฐ ์ ๊ทผํ๋ ์ฌ๋์ด ์ง์ง A์ธ์ง ํ์ธํ๋ ์ ์ฐจ)์ด๊ณ , Authorization์ ์ด๋ ํ ์ ์ ๊ฐ ํน์ ์์์ ์ ๊ทผํ๋ ค ํ ๋, ๊ทธ์๋ํ ์ ๊ทผ ๊ถํ์ด ์๋์ง ํ์ธํ๋ ์ ์ฐจ์ ๋๋ค.
- ์์ฒญ ์ ์ฐจ์ ๋จ์ํ
API Gateway๋ ์ฌ๋ฌ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ๋จ์ผ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ผ๋ก ๋์ฒด ๊ฐ๋ฅํ๋๋ก ํฉ๋๋ค. ๋ฐ๋ผ์ ํด๋ผ์ด์ธํธ์ ๋ฐฑ์๋ ๊ฐ์ API ํต์ ๋์ ์ค์ฌ์ฃผ์ด ๋๊ธฐ์๊ฐ์ ์ค์ด๊ณ ํจ์จ์ฑ์ ๋์ฌ์ค ์ ์์ต๋๋ค.
- ๋ผ์ฐํ ๋ฐ ๋ก๋๋ฐธ๋ฐ์ฑ
API Gateway๋ ํด๋ผ์ด์ธํธ๋ก ๋ถํฐ ์ ์๋ ๋ฉ์ธ์ง์ ๋ฐ๋ผ, API ํธ์ถ์ ์ ์ ํ ์๋น์ค์ ๋ผ์ฐํ ํ ์ ์๋ ๊ธฐ๋ฅ์ด ์์ต๋๋ค. ๋ํ, ์๋น์ค ์ธ์คํด์ค๋ค์ ๋ํ ๋ถํ๋ถ์ฐ์ ํ ์ ์์ต๋๋ค.
- ์๋น์ค ์ค์ผ์คํธ๋ ์ด์
์ค์ผ์คํฌ๋ ์ด์ ์ ์ฌ๋ฌ๊ฐ์ ๋ง์ดํฌ๋ก ์๋น์ค๋ฅผ ๋ฌถ์ด ์๋ก์ด ์๋น์ค๋ฅผ ๋ง๋๋ ๊ฐ๋ ์ ๋๋ค. ์ค์ผ์คํธ๋ ์ด์ ๋ก์ง์ ๊ณผ๋ํ๊ฒ ๋ฃ๋ ๊ฒ์, API Gateway์ ๋ถ๋ด์ ๋๋ฆฌ๋ ๊ฒ์ผ๋ก, ์ฑ๋ฅ ์ ํ๋ฅผ ์ผ์ผํฌ ์ ์์ด, MSA์ API Gateway์ ๋ํ ๋์ ์์ค์ ๊ธฐ์ ์ ์ดํด๋ฅผ ๋ฐํ์ผ๋ก ์ด๋ฃจ์ด์ ธ์ผ ํฉ๋๋ค.
- ์๋น์ค ๋์ค์ปค๋ฒ๋ฆฌ
ํด๋ผ์ฐ๋ ํ๊ฒฝ์์๋ ๋์ ์ธ ํ๊ฒฝ์์ ๋ฐฐํฌ๋๊ธฐ ๋๋ฌธ์ ์๋น์ค์ ์์น๋ฅผ ์ฐพ๋ ๊ฒ์ด ์ด๋ ต์ต๋๋ค. ์ด๋ฌํ ์๋น์ค์ ์์น(IP ์ฃผ์์ ํฌํธ๋ฒํธ)๋ฅผ ์ฐพ๋ ๊ฒ์ โService Discoveryโ๋ผ ํ๋ฉฐ, API Gateway์์๋ ์๋ฒ์ฌ์ด๋๋, ํด๋ผ์ด์ธํธ ์ฌ์ด๋๋ฅผ ๊ธฐ์ค์ผ๋ก ํ์ฌ ์๋น์ค ๋์ค์ปค๋ฒ๋ฆฌ๋ฅผ ๊ตฌํํ ์ ์์ต๋๋ค.
๐ฟ APi Gateway ๊ณ ๋ ค ์ฌํญ
- Api Gateway๋ฅผ ๋ด๋ถ ms์ ๊ฒฐํฉํ๋ค๋ ๊ฒ: SOA์์์ ESB๋ฌธ์ ์์ ๋ฐ์ํ๋ ๋ฌธ์ ์ ์ด ๋ค์ ๋ฐ์ ๊ฐ๋ฅ
- ESB ๋ด๋ถ ์ฒ๋ฆฌ ๋ก์ง์ XML์ ๊ธฐ๋ฐ์ผ๋ก ํ์๋๋ฐ, XML์ ํ์ฑ์ ์ค๋ฒํค๋๊ฐ ํฐ ์์
- ๊ณผ๋ํ Orchestration ๋ฑ ๋ฌด๊ฑฐ์ด ๋ก์ง์ ๊ฐ์ง๊ณ ์์์ต๋๋ค. ํนํ ESB๋ฅผ Gateway๋ก์ ํน์ฑ์ด ์๋ ์์คํ ์ ํตํฉํ๊ธฐ ์ํ ์ญํ ๋ก ๋ง์ด ๊ตฌํํ์๊ธฐ ๋๋ฌธ์ ๋ง์ ์คํจ ์ฌ๋ก๊ฐ ๋ฐ์
- Gateway์ Scale-Out ์ ์ฉ์ ์ํ ํ์ง ์์ ๊ฒฝ์ฐ Api Gateway๊ฐ ๋ณ๋ชฉ์ง์ ์ด ๋ ๊ฐ๋ฅ์ฑ
- ์ถ๊ฐ ์ ์ธ gateway๋ผ๋ ๊ณ์ธต ์์ฑ์ผ๋ก ์ธํ ์๋ ์ ํ
๐ฟ Spring Cloud Gateway
- Spring Cloud Eureka Server(Discovery Service)์ ๊ฒฐํฉ
- ์ธ์ฆ ๋ฐ ์ธ๊ฐ ์๋น์ค
Filter
์ข ๋ฅ
- GlobalFilter
- CustomFilter
- PreFilter
- PostFilter
CustomFilter ์์ฑ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Component
@Slf4j
public class CustomAuthFilter extends AbstractGatewayFilterFactory<CustomAuthFilter.Config> {
public CustomAuthFilter() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return ((exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
if(config.isPreLogger()) {
log.info("PreLogger");
}
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
if(config.isPostLogger()) {
log.info("PostLogger");
}
}));
});
}
@Data
public static class Config {
private String baseMessage;
private boolean preLogger;
private boolean postLogger;
}
}
CustomFilter ๋ฑ๋ก
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
server:
port: 8000
spring:
application:
name: gateway-service
cloud:
gateway:
routes:
- id: user-service
uri: lb://USER-SERVICE
predicates:
- Path=/user/**
filters:
- RewritePath=/user/?(?<segment>.*), /$\{segment}
- name: CustomAuthFilter
args:
baseMessage: Hi, there.
preLogger: true
postLogger: true
- id: order-service
uri: lb://ORDER-SERVICE
predicates:
- Path=/order/**
filters:
- RewritePath=/user/?(?<segment>.*), /$\{segment}
- RewritePath: Gateway๋ก ์์ฒญ์ด ๋ค์ด์ค๋ฉด Path ๊ฐ์ ์๋์ผ๋ก ์ฌ์์ฑ
- predicates: Gateway๋ก ๋ค์ด์จ ์์ฒญ์ ๋ฐ๋ผ Load balancing
- ์๋ฅผ ๋ค์๋ฉด /order/** (์ค๋๋ก ๋ค์ด์จ ์์ฒญ ์ ServiceDiscovery์์ ORDER-SERVICE์ URL ๋์ ์ผ๋ก ์ฐพ์์ ์์ฒญ์ ๋ณด๋)
- lb๋ service Discovery์์ URL์ ๊ฒ์ํ๊ฒ ๋ค๋ ๋ป
- name: filter๋ฅผ preFilter์ postFilter๋ฅผ ๊ตฌ๋ถํด์ ์ฌ์ฉํ๊ณ ์ถ๋ค๋ฉด name์ ๋ถํ Filter๋ฅผ ์ ์ํ๊ณ args๋ฅผ ์ด๊ธฐํํ๋ ๋ถ๋ถ์ ์์ฑํด์ผ ํจ
GlobalFilter ์์ฑ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Component
@Slf4j
public class GlobalFilter extends AbstractGatewayFilterFactory<GlobalFilter.Config> {
public CustomAuthFilter() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return ((exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
if(config.isPreLogger()) {
log.info("PreLogger");
}
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
if(config.isPostLogger()) {
log.info("PostLogger");
}
}));
});
}
@Data
public static class Config {
private String baseMessage;
private boolean preLogger;
private boolean postLogger;
}
}
GlobalFilter ๋ฑ๋ก
1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
default-filters:
- name: GlobalFilter
args:
baseMessage: Spring Cloud GlobalFilter
preLogger: true
postLogger: true
routes: ...