티스토리 뷰
2.1.0.RELEASE 문서를 번역한 내용
1. Spring Cloud Gateway 를 포함시키는 방법
프로젝트에 Spring Cloud Gateway 를 포함시키기 위해서는 org.springframework.cloud 로 시작하는 group 과 spring-cloud-starter-gateway 의 artifact id 를 사용해야 한다. Spring Cloud Project 페이지에서 자세한 세팅 방법을 확인할 수 있다.
stater 를 사용하지만 gateway 를 disable 하고 싶다면 아래 설정값을 추가하면 된다.
spring.cloud.gateway.enabled=false
Spring Boot + Spring Cloud Gateay build.gradle 예시
plugins {
id 'org.springframework.boot' version '2.3.1.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
}
group = 'com.woongs'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-gateway', version: '2.2.1.RELEASE'
compile group: 'log4j', name: 'log4j', version: '1.2.17'
compile "org.projectlombok:lombok:1.16.6"
}
test {
useJUnitPlatform()
}
2. 용어 설명
- Route : Route 는 Gateway 를 이루는 기본 단위. ID 로 정의되며, 도착 URI, predicate 들과 filter 들의 모음이다. predicate 가 모두 충족되면 Route 가 매칭된다.
- Predicate : Java8 Function Predicate 이다. Input 타입은 Spring Framework 의 ServerWebExchange 이다. Header 와 Parameter 와 같은 HTTP 구성 요소들로 개발자가 Matching 여부를 판단할 수 있도록 도와준다.
- Filter : Spring Framework 의 GatewayFilter 이다. downstream 으로 요청을 보내기 전과 후에 Request 와 Response 를 수정할 수 있게 해준다.
3. 동작 원리
클라이언트가 Spring Cloud Gateway 로 요청을 보낸다. 만약 Gateway Handler Mapping 이 Route 에 요청이 매칭되었다고 판단한다면, Gateway Web Handler 로 요청을 보낸다. Gateway Web Handler 는 해당 요청에 특정된 필터 체인을 통하여 요청을 보내게 된다. 필터들이 점선으로 나뉘어진 이유는 Proxy Request 가 보내지기 전 또는 후에 실행되기 때문이다. 모든 "pre" 필터 로직이 실행된 후에 Proxy Request 가 생성되며 Proxy Request 가 생성된 후에 "post" 필터 로직이 수행된다.
4. Route Predicate Factories
Spring Cloud Gateway 는 Spring WebFlux 의 HandlerMapping 구조로 Route 를 매칭한다. Spring Cloud Gateway 는 많은 종류의 Route Predicate Factory 를 포함하고 있다. 이 모든 predicate 들은 HTTP 요청의 서로 다른 속성을 매칭시킬 수 있다. 여러개의 Multiple Route Predicate Factory 들은 "and" 를 이용하여 결합될 수 있다.
4.1 After Route Predicate Factory
After Route Predicate Factory 는 DateTime 을 파라미터로 받는다. 현재 DateTime 이후에 발생한 요청들에 대해서 매칭된다.
spring:
cloud:
gateway:
routes:
- id: after_route
uri: http://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
2017년 1월 20일 17:42 이후에 생성된 요청들에 대해서 Route 가 매칭된다.
4.2 Before Route Predicate Factory
Before Route Predicate Factory 는 DateTime 을 파라미터로 받는다. 현재 DateTime 이전에 발생한 요청들에 대해서 매칭된다.
spring:
cloud:
gateway:
routes:
- id: after_route
uri: http://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
2017년 1월 20일 17:42 이전에 생성된 요청들에 대해서 Route 가 매칭된다.
4.3 Between Route Predicate Factory
Between Route Predicate Factory 는 두개의 DateTime 파라미터를 받는다. DateTime1 과 DateTime2 사이에 발생한 요청들에 대해서 매칭된다.
spring:
cloud:
gateway:
routes:
- id: between_route
uri: http://example.org
predicates:
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
2017년 1월 20일 17:42 부터 2017년 1월 21일 17:42 까지 발생한 요청들에 대해서 매칭되며 시스템 조정 등에 사용될 수 있다.
4.4 Cookie Route Predicate Factory
Cookie Route Predicate Factory 는 Cookie 이름과 정규표현식을 파라미터로 받는다. 주어진 쿠키 이름과 해당 값이 정규표현식에 매칭되면 매칭된다.
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: http://example.org
predicates:
- Cookie=chocolate, ch.p
chocolate 이라는 쿠키를 가지고 있으며 value 가 ch.p 정규표현식에 매칭되면 해당 Route 가 매칭된다.
4.5 Header Route Predicate Factory
Header Route Predicate Factory 는 헤더 이름과 정규표현식을 파라미터로 받는다. 해당 헤더를 가지고 있으며 값이 정규표현식에 맞는다면 매칭된다.
spring:
cloud:
gateway:
routes:
- id: header_route
uri: http://example.org
predicates:
- Header=X-Request-Id, \d+
X-Request-Id 를 헤더로 가지고 있으며 값이 \d+ 에 맞는다면 매칭된다. (하나 이상의 digit)
4.6 Host Route Predicate Factory
Host Route Predicate Factory 는 호스트 패턴 리스트를 파라미터로 받는다. 이 패턴은 Ant 스타일 패턴이며 . 를 구분자로 사용한다.
이 predicate 는 Host 헤더가 패턴에 일치하는지 확인한다.
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org
이 Route 는 요청이 Host 헤더를 포함하고 있으며 Value 가 www.somehost.org 또는 beta.somehost.org 또는 www.anotherhost.org 일 경우에 매칭된다.
Host Route Predicate 는 URI Template 값을 이름과 값 Map 으로 추출하여 ServerWebExchange.getAttributes() 에 저장한다. 이때 키는 ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE 이다. 이 변수들은 GatewayFilter Factories 에서도 사용 가능하다.
4.7 Method Route Predicate Factory
Method Route Predicate Factory 는 HTTP 메소드를 파라미터로 사용한다.
spring:
cloud:
gateway:
routes:
- id: method_route
uri: http://example.org
predicates:
- Method=GET
Request Method 가 GET 인 경우에 매칭된다.
4.8 Path Route Predicate Factory
Path Route Predicate Factory 는 Spring 의 PathMatcher 패턴 리스트와 matchOptionalTrailingSeparator 를 옵셔널 플래그로 사용한다.
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://example.org
predicates:
- Path=/foo/{segment},/bar/{segment}
위 Route 는 Request Path 가 /foo/1 또는 /foo/gar 또는 /bar/baz 일 경우에 매칭된다.
Host Route Predicate 는 URI Template 값을 이름과 값 Map 으로 추출하여 ServerWebExchange.getAttributes() 에 저장한다. 이때 키는 ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE 이다. 이 변수들은 GatewayFilter Factories 에서도 사용 가능하다.
이 값들을 더 쉽게 사용하기 위한 유티리티 메서드가 존재한다.
Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);
String segment = uriVariables.get("segment");
4.9 Query Route Predicate Factory
Query Route Predicate Factory 는 Param 을 필수로 regexp 를 옵셔널로 파라미터에 사용한다.
spring:
cloud:
gateway:
routes:
- id: query_route
uri: http://example.org
predicates:
- Query=baz
baz 를 쿼리 파라미터로 사용하는 요청에 매칭된다.
spring:
cloud:
gateway:
routes:
- id: query_route
uri: http://example.org
predicates:
- Query=foo, ba.
foo 를 쿼리 파라미터로 사용하고 value 가 ba. 정규 표현식에 맞는다면 매칭된다.
4.10 Retmote Addr Route Predicate Factory
최소 하나 이상의 CIDR (IPv4 또는 IPv6) 를 파라미터로 받는다.
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: http://example.org
predicates:
- RemoteAddr=192.168.1.1/24
remote address 가 CIDR 에 맞는다면 매칭된다. (192.168.1.10)
4.10.1 remote address 가 수정되는 경우
기본적으로 RemoteAddr Route Predicate Factory 는 들어오는 요청의 remote address 를 사용한다. 하지만 만약 Spring Cloud Gateway 가 Proxy 레이어 이후에 있다면 remote address 는 실제 Client 의 IP 가 아닐 수 있다.
따라서 RemoteAddressResolver 를 커스터마이징 한다면 이 문제를 해결할 수 있다. Spring Cloud Gateway 는 X-Forwarded-For header 를 사용하는 XForwardedRemoteAddressResolver 를 기본으로 사용한다.
XForwardedRemoteAddressResolver 는 두개의 생성자 메서드를 제공한다.
- XForwardedRemoteAddressResolver::trustAll 는 X-Forwarded-For 헤더에 첫번째 IP 를 사용하는 RemoteAddressResolver 를 리턴한다.
- XForwardedRemoteAddressResolver::maxTrustedIndex 는 Spring Cloud Gateway 앞단에서 실행되고 있는 시스템들의 갯수를 index 로 받는다. 만약 Spring Cloud Gateway 가 HAProxy 를 통해서 접근할 수 있다면 index 는 1이 되어야 한다. 만약 2개의 시스템이 Spring Cloud Gateway 앞에 있다면 index 는 2가 되어야 한다.
X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3
Spring Cloud Gateway 가 받는 요청의 헤더에 위와 같이 전달된다면 maxTrustedIndex 는 아래와 같이 동작하게 된다.
[Integer.MIN_VALUE,0] |
(invalid, IllegalArgumentException during initialization) |
1 |
0.0.0.3 |
2 |
0.0.0.2 |
3 |
0.0.0.1 |
[4, Integer.MAX_VALUE] |
0.0.0.1 |
Java config 예제
RemoteAddressResolver resolver = XForwardedRemoteAddressResolver
.maxTrustedIndex(1);
...
.route("direct-route",
r -> r.remoteAddr("10.1.1.1", "10.10.1.1/24")
.uri("https://downstream1")
.route("proxied-route",
r -> r.remoteAddr(resolver, "10.10.1.1", "10.10.1.1/24")
.uri("https://downstream2")
5. GatewayFilter Factories
Route Filter 는 들어오는 HTTP Request 와 나가는 HTTP Response 를 몇몇 방법을 통하여 수정할 수 있다. Spring Cloud Gateway 는 많은 구현된 GatewayFilter Factory 를 제공한다.
더 자세한 코드레벨을 보고 싶다면 여기를 참고!
5.1 AddRequestHeader Gateway Filter Factory
AddRequestHeader Gateway Filter Factory 는 name 과 value 를 파라미터로 받는다.
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: http://example.org
filters:
- AddRequestHeader=X-Request-Foo, Bar
모든 매칭되는 요청에 대해서 X-Request-Foo:Bar 를 헤더에 추가한다.
5.2 AddRequestParameter GatewayFilter Factory
name 과 value 두개의 파라미터를 받는다.
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: http://example.org
filters:
- AddRequestParameter=foo, bar
매칭 되는 모든 요청에 대해서 Request Query String 이 추가된다 (foo=bar)
5.3 AddResponseHeader GatewayFilter Factory
name 과 value 를 파라미터로 받는다.
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: http://example.org
filters:
- AddResponseHeader=X-Response-Foo, Bar
매칭 되는 모든 요청에 대해서 X-Response-Foo:Bar 를 헤더에 추가한다.
5.4 Hystrix GatewayFilter Factory
Hystrix 는 Circurit Breaker Pattern 을 구현한 넷플릭스에서 만든 라이브러리이다. Hystrix GatewayFilter 는 Gateway Route 에 Circurit breaker 를 도입할 수 있게 해준다. 이는 서비스가 연속적으로 실패하는것으로부터 보호할 수 있으며 downstream 의 장애 발생시 fallback 응답을 제공할 수 있게 해준다.
Hystrix GatewayFilter 를 사용하기 위해서는 spring-cloud-starter-netflix-hystrix 를 의존성에 추가해야한다.
Hystrix GatewayFilter Factory 는 name 파라미터를 받는다. 이 것은 HystrixCommand 의 이름이다.
spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: http://example.org
filters:
- Hystrix=myCommandName
Hystrix 필터는 fallbackUri 파라미터를 선택적으로 받을 수 있다. 현재 오로지 forward: 만 허용된다. fallback 이 불리게 되면 URI 에 매칭되는 컨트롤러로 포어드 된다.
spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: lb://backing-service:8088
predicates:
- Path=/consumingserviceendpoint
filters:
- name: Hystrix
args:
name: fallbackcmd
fallbackUri: forward:/incaseoffailureusethis
- RewritePath=/consumingserviceendpoint, /backingserviceendpoint
Hystrix fallback 이 불리게 되면 /incaseoffailuresethis 로 포워딩 한다. 이 예제는 Spring Cloud Netflix Ribbon 의 load-balancing 을 도착 URI prefix 로 사용하고 있다.
기본적으로 fallbackUri 는 Spring Cloud Gateway 내부의 Controller 로 맵핑되지만 외부 application 으로 reroute 하는 것도 가능하다.
spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: Hystrix
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
위 예제에서는 fallback endpoint 또는 gateway application 의 핸들러가 존재하지 않지만 http://localhost:9994 아래에 등록되어있는 또 다른 app 이 존재한다.
fallback 으로 요청이 포워딩 되는 경우에, Hystrix GatewayFilter 는 Fallback 의 원인이 되는 Throwable 를 제공한다. ServerWebExchange 에 ServerWebExchangeUtils.HYSTRIX_EXECUTION_EXCEPTION_ATTR 속성을 추가해준다.
Exception Detail 이 헤더에 추가될 수 있다. 자세한 내용은 FallBackHeaders GatewayFilter Factory section 에서 참고할 수 있다.
Hystrix 설정은 Global 기본 설정을 사용할 수도 있고 Route 별로 설정을 할 수 있다. 여기 참고.
5.5 FallbackHeaders GatewayFilter Factory
FallbackHeaders Factory 는 Hystrix 실행 예외의 디테일한 정보를 헤더에 포함시켜 fallbackUri 로 전달할 수 있다.
spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: Hystrix
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
filters:
- name: FallbackHeaders
args:
executionExceptionTypeHeaderName: Test-Header
HystrixCommand 를 실행하는 도중에 발생한 예외를 실행한 후에 fallback 엔드포인트인 localhost:9994 로 포워딩 될 것이다. 헤더에는 Exception Type, 메시지 그리고 가능하다면 root cause exception type 과 메시지가 FallbackHeaders 필터에 의해서 추가될 것이다.
5.6 PrefixPath GatewayFilter Factory
prefix 를 파라미터로 받는다.
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: http://example.org
filters:
- PrefixPath=/mypath
매칭되는 모든 요청에 /mypath 를 경로에 prefix 로 추가한다. /hello 요청이 들어온다면 /mypath/hello
5.7 PreserveHostHeader GatewayFilter Factory
PreseveHostHeader 는 파라미터가 없다. 이 필터는 http client 에 의해서 host header 가 결정되었는지를 확인한다.
spring:
cloud:
gateway:
routes:
- id: preserve_host_route
uri: http://example.org
filters:
- PreserveHostHeader
5.8 RequestRateLimiter GatewayFilter Factory
RequestRateLimiter GatewayFilter 는 현재 요청이 처리되어도 되는지 결정하기 위하여 RateLimiter 를 구현한다. 만약 처리될 수 없다면 디폴트로 HTTP 429 - Too Many Requests 를 리턴한다.
필터는 옵션으로 keyResolver 를 파라미터로 받는다. 이 파라미터는 RateLimit 에 사용할 키를 특정한다.
keyResolver 는 KeyResolver 를 구현한 빈이다.
public interface KeyResolver {
Mono<String> resolve(ServerWebExchange exchange);
}
KeyResolver 는 요청을 제한할때 사용할 키를 변경할 수 있도록 도와준다. 앞으로는 KeyResolver 구현체가 생길것이다.
디폴트로는 PrincipalNameKeyResolver 를 사용하게 된다. 이 리졸버는 Principal 를 ServerWebExchange 로 부터 얻어오고 Principal 에서 Pincipal.getName() 을 호출한다.
KeyResolver 가 키를 찾지 못한다면 디폴트 정책은 해당 요청을 막는다. 위 설정은 아래 설정값으로 변경될 수 있다.
- spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key : ture
- spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code
5.8.1 Redis RateLimiter
Redis 를 사용하기 위해서는 아래 의존성이 추가되어야 한다.
spring-boot-starter-data-redis-reactive
이때 사용되는 알고리즘은 Token Bucket Algorithm 이다.
- redis-rate-limiter.replenishRate : 1초당 몇개까지 요청을 허용할지에 대한 속성 값이다. token buket 이 가득 차는 값. token bucket 에서 downstream 으로 흐르는 요청양 같다.
- redis-rate-limiter.burstCapacity : 1초에 최대 몇개까지 요청을 보낼 수 있는지에 대한 속성 값이다. token bucket 이 가지고 있을 수 있는 토큰 갯수이다. 이 값을 0 으로 설정하면 모든 요청이 block 된다
replenishRate 와 burstCapacity 를 같은 값으로 설정하면 동일한 값이 적용된다. 일시적으로 제한을 걸기 위해서는 burstCapacity 를 replenishRate 보다 큰 값으로 설정하면 된다. 이 경우에 Rate Limiter 는 replenishRate 에 따라서 허용된다. 2번의 연이은 초과는 요청이 블락되는 결과를 낳는다.
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: http://example.org
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
@Bean
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
위 설정은 하나의 사용자당 10개의 요청을 제한한다. 20건 까지 bucket 에 담기는 것을 허용하지만, 다음 1초 동안 10 건의 요청만 가능하다.
RateLimiter 를 구현하면 커스터마이징된 RateLimiter 를 사용할 수 있다. 설정에 보면 #{@myRateLimiter} 와 같이 사용한다.
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: http://example.org
filters:
- name: RequestRateLimiter
args:
rate-limiter: "#{@myRateLimiter}"
key-resolver: "#{@userKeyResolver}"
5.9 RedirectTo Gateway Filter Factory
status 과 url 을 파라미터로 받는다. Status 는 300 대의 응답 코드를 사용해야만 한다. 유효한 url 을 사용해야하며 이것은 Location header 의 값이 된다.
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: http://example.org
filters:
- RedirectTo=302, http://acme.org
위 설정은 매칭되는 uri 에 대해서 리다이렉 시키기 위하여 헤더에 Location:http://acme.org 를 포함시킨다.
5.10 RemoveNonProxyHeaders GatewayFilter Factory
요청을 포워딩할때 헤더를 제거할 수 있다. 기본적으로 제거할 수 있는 헤더들의 리스트는 아래와 같다.
- Connection
- Keep-Alive
- Proxy-Authenticate
- Proxy-Authorization
- TE
- Trailer
- Transfer-Encoding
- Upgrade
위 리스트를 변경하고 싶다면 spring.cloud.gateway.filter.remove-non-proxy-headers.headers 프로퍼티에 제거하고자 하는 헤더 이름을 추가하면 된다.
5.11 RemoveRequestHeader GatewayFilter Factory
name 을 파라미터로 받으며 파라미터로 받은 name 을 헤더에서 제거한다.
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: http://example.org
filters:
- RemoveRequestHeader=X-Request-Foo
X-Request-Foo 헤더가 제거된 후에 downstream 시스템으로 전달된다.
5.12 RemoveResponseHeader GatewayFilter Factory
name 을 파라미터로 받으며 응답에서 name 헤더를 제거한다.
spring:
cloud:
gateway:
routes:
- id: removeresponseheader_route
uri: http://example.org
filters:
- RemoveResponseHeader=X-Response-Foo
X-Response-Foo 헤더가 Rseponse 에서 제거되어 클라이언트에게 전달된다.
5.13 RewritePath GatewayFilter Factory
regexp 와 replacement 파리미터를 받는다. 유연한 rewrite path 를 위하여 자바 정규표현식을 사용한다.
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: http://example.org
predicates:
- Path=/foo/**
filters:
- RewritePath=/foo/(?<segment>.*), /$\{segment}
/foo/bar 에 매칭되는 요청은 정규표현식에 의해서 /bar 로 수정되어 downstream 으로 전달된다. $₩ 신텍스는 YAML 스펙에 의해서 $ 로 변경되었다는것을 기억하자!
5.14 RewriteResponseHeader GateayFilter Factory
name, regexp 와 replacement 를 파라미터로 받는다.
spring:
cloud:
gateway:
routes:
- id: rewriteresponseheader_route
uri: http://example.org
filters:
- RewriteResponseHeader=X-Response-Foo, , password=[^&]+, password=***
헤더 값인 42?user=ford&password=omg!what&flag=true 는 RewriteResponseHeader 필터에 의해서 /42?user=ford&password=***&flag=true 로 변경된다.
5.15 SaveSession GatewayFilter Factory
SaveSession 필터는 WebSession::save 함수를 dwonstream 으로 요청을 전달하기 전에 강제적으로 호출한다. Spring Session 과 같이 lazy data store 와 downstream 으로 요청을 전달하기 전에 세션 상태가 저장되어야만 할때 사용된다.
spring:
cloud:
gateway:
routes:
- id: save_session
uri: http://example.org
predicates:
- Path=/foo/**
filters:
- SaveSession
Spring Security 의 Spring Session 을 연동하여 사용하고 있고 다른 리모트에 보안 디테일을 보장하고 싶다면 이 기능이 영향을 미칠 것이다.
5.16 SecureHeaders GatewayFilter Factory
SecureHeaders 는 이 블로그에서 추천하는 많은 헤더들을 추가해준다.
- X-Xss-Protection:1; mode=block
- Strict-Transport-Security:max-age=631138519
- X-Frame-Options:DENY
- X-Content-Type-Options:nosniff
- Referrer-Policy:no-referrer
- Content-Security-Policy:default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'
- X-Download-Options:noopen
- X-Permitted-Cross-Domain-Policies:none
위 기본값들을 변경하고 싶다면 아래 프로퍼티로 수정할 수 있다.
spring.cloud.gateway.filter.secure-headers
- xss-protection-header
- strict-transport-security
- frame-options
- content-type-options
- referrer-policy
- content-security-policy
- download-options
- permitted-cross-domain-policies
5.17 SetPath GatewayFilter Factory
template 을 파라미터로 받는다. 템플릿화된 부분을 이용하여 요청 Path 를 다룰 수 있게 해준다. Spring Framework 의 uri 템플렛을 사용한다.
spring:
cloud:
gateway:
routes:
- id: setpath_route
uri: http://example.org
predicates:
- Path=/foo/{segment}
filters:
- SetPath=/{segment}
/foo/bar 요청이 /bar 로 변경되어 downstream 에 전달된다.
5.18 SetResponseHeader GatewayFilter Factory
name 과 value 를 파라미터로 받는다.
spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: http://example.org
filters:
- SetResponseHeader=X-Response-Foo, Bar
SetResponseHeader 는 헤더를 추가하는 것이 아니라 기존에 있는 헤더 값을 변경하는데 사용한다. 만약 downstream 시스템이 X-Response-Foo:1234 라는 값을 헤더에 포함시킨다면 X-Response-Foo:Bar 로 헤더값을 변경한다.
5.19 SetStatus GatewayFilter Factory
status 를 파리미터로 받는다. status 는 HttpStatus 의 유효한 값이 전달되어야 하나다. 404 와 같은 Integer 값 혹은 NOT_FOUND 같은 Enum 이 전달되어야 한다.
spring:
cloud:
gateway:
routes:
- id: setstatusstring_route
uri: http://example.org
filters:
- SetStatus=BAD_REQUEST
- id: setstatusint_route
uri: http://example.org
filters:
- SetStatus=401
매칭되는 요청에대해서 HttpStatus 를 전달받은 값으로 설정한다.
5.20 StripPrefix GatewayFilter Factory
parts 를 파라미터로 받는다.
spring:
cloud:
gateway:
routes:
- id: nameRoot
uri: http://nameservice
predicates:
- Path=/name/**
filters:
- StripPrefix=2
http://nameservice/name/bar/foo 로 들어온 요청은 http://nameservice/foo 로 변경될 것이다.
5.21 Retry GatewayFilter Factory
retires, statuses, methods and series 를 파라미터로 받는다.
- retries : 시도될 재시도 횟수.
- statuses : 재시도될 HTTP 상태값들. org.springframework.http.HttpStatus
- methods : 재시도될 HTTP Method 들. org.springframework.http.HttpMethod
- series : 재시도될 Series. org.springframework.http.HttpStatus.Series
spring:
cloud:
gateway:
routes:
- id: retry_test
uri: http://localhost:8080/flakey
predicates:
- Host=*.retry.com
filters:
- name: Retry
args:
retries: 3
statuses: BAD_GATEWAY
5.22 RequestSize GatewayFilter Factory
설정된 값보다 request size 가 큰 경우에 요청을 제한할 수 있다. RequestSize 를 파라미터로 받는다. Byte 단위이다.
spring:
cloud:
gateway:
routes:
- id: request_size_route
uri: http://localhost:8080/upload
predicates:
- Path=/upload
filters:
- name: RequestSize
args:
maxSize: 5000000
500000Byte 를 초과하는 request body 에 대해서 413 Payload Too Large 응답을 리턴하며 추가로 헤더에 errorMessage 에 최대 사이즈를 리턴해준다.
5.23 Modify Request Body GatewayFilter Factory < BETA 버전!
downstream 으로 요청을 전달하기 전에 Request Body 를 수정할 수 있다.
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("rewrite_request_obj", r -> r.host("*.rewriterequestobj.org")
.filters(f -> f.prefixPath("/httpbin")
.modifyRequestBody(String.class, Hello.class, MediaType.APPLICATION_JSON_VALUE,
(exchange, s) -> return Mono.just(new Hello(s.toUpperCase())))).uri(uri))
.build();
}
static class Hello {
String message;
public Hello() { }
public Hello(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
5.24 Modfy Response Body GatewayFilter Factory < BETA 버전!
Client 에게 응답을 전달하기 전에 Response Body 를 수정할 수 있다.
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org")
.filters(f -> f.prefixPath("/httpbin")
.modifyResponseBody(String.class, String.class,
(exchange, s) -> Mono.just(s.toUpperCase()))).uri(uri)
.build();
}
6. Global Filters
GlobalFilter 는 GatewayFilter 와 같은 시그니쳐를 갖는다. 모든 Route 에 적용할 수 있는 특별한 필터이다.
6.1 Combined Global Filter and GatewayFilter Ordering
요청이 Gateway 로 인입되고 Route에 매칭되었을때 Filtering Web Handler 는 모든 객체에 GoblalFilter 를 추가한다. 그리고 모든 Route 의 Filter chain 에 Global Filter 를 추가한다. 이렇게 결합된 필터들은 org.springframework.core.Ordered 에 의해서 정렬된다.
Spring Cloud Gateway 는 필터 로직을 수행할때 "pre" 와 "post" 를 구분하기 때문에, 가잔 우선순위가 높은 필터의 "pre" 필터가 먼저 수행되며 "post" 구문이 가장 늦게 수행된다.
@Bean
@Order(-1)
public GlobalFilter a() {
return (exchange, chain) -> {
log.info("first pre filter");
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("third post filter");
}));
};
}
@Bean
@Order(0)
public GlobalFilter b() {
return (exchange, chain) -> {
log.info("second pre filter");
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("second post filter");
}));
};
}
@Bean
@Order(1)
public GlobalFilter c() {
return (exchange, chain) -> {
log.info("third pre filter");
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("first post filter");
}));
};
}
6.2 Forward Routing Filter
Forward Routing Filter 는 excahnge 속성 값중 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 를 바라본다.
URL 에 forward scheme (forward://localendpoint) 를 가지고 있다면 Spring Cloud Gateway 는 이 요청을 처리하기 위하여 DispatcherHandler 를 사용한다.
요청 URL 의 Path 를 forward URL 로 엎어치게된다. 수정되지 않은 기존의 URL 은 ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR 에 저장된다.
6.3 LoadBalancerClient Filter
LoadBalancerClient 필터는 Exchange 속석 값중 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 를 바라본다. 만약 url 구조중에 lb scheme (lb://mysevice) 를 가지고 있다면, SPring Cloud 의 LoadBalancerClient 를 를 사용하여 myservice 의 실제 호스트와 포트를 찾아 URI 를 대체한다. 수정되지 않은 기존의 URL 은 ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR 속성에 저장된다.
spring:
cloud:
gateway:
routes:
- id: myRoute
uri: lb://service
predicates:
- Path=/service/**
LoadBalancer 에서 서비스 인스턴스를 찾을 수 없다면 기본적으로 503 을 리턴한다.
아래 설정을 이용하여 404 로 변경할 수 있다.
spring.cloud.gateway.loadbalancer.use404=true
'Spring Framework > Spring Cloud' 카테고리의 다른 글
Spring Cloud Gateway dynamic configuration change (0) | 2020.11.29 |
---|---|
Spring Cloud Gateway mapping custom data to configuration - Route meta data to RoutePredication (0) | 2020.11.29 |
Spring Cloud Gateway mapping custom data to configuration - Meta Data 정의 (0) | 2020.11.29 |
Spring Cloud Gateway 프로젝트 세팅 (0) | 2020.08.04 |
Spring Cloud Gateway RateLimiter 적용 (1) | 2020.08.04 |
- Total
- Today
- Yesterday
- notify()
- referencedColumnName
- wait()
- custom config data convertion
- spring cloud gateway
- reative
- N+1
- rate limit
- RouteDefinition
- MariaDB
- dynamodb
- aurora
- reactor
- mariadb-connector-j
- HashMap
- getBoolean
- Seperate Chaining
- Flux
- RoutePredication
- ConcurrentHashMap
- msyql-connector-java
- AbstractMethodError
- mariada-connector
- ResultSet
- GlobalFilter
- circurit breaker
- notifyAll()
- DyanomoDB
- Lazy
- router
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |