1. 序言
Gateway配置文件非常强大,基本已经包含了大部分的使用场景,我们一般直接通过配置文件就可以完成配置了
2. 开启根据微服务名转发
1
| spring.cloud.gateway.discovery.locator.enabled=true
|
开启此配置后会根据链接的path第一层寻找对应的微服务名,并且转发后会将第一层微服务名给去掉,保留后面的内容发给后续应用,
如: provider注册的服务名为CloudGatewayProvider
,提供的服务路径为/providerController/hello
,自身的servlet.context-path
为/cloud-provider
,如图:
nacos

controller

application.yml

通过访问以下路径可以得到provider数据,
类似于nginx的转发重写功能
1
| localhost:8101/CloudGatewayProvider/cloud-provider/providerController/hello
|
3. 手动配置路由映射
此种方式手动配置路由映射,如:
1 2 3 4 5 6 7 8
| spring: cloud: gateway: routes: - id: nacos-provider uri: lb://CloudGatewayProvider predicates: - Path=/cloud-provider/**
|
- id 配置的id为全局唯一,只要唯一就可以
- uri 为访问的地址,即匹配到路径之后怎么转发
- predicates 为匹配规则,上文是匹配到路径为/cloud-provider开头的所有请求都转发至微服务CloudGatewayProvider中,需要注意的是此种方式不会将匹配路径
/cloud-provider
舍弃
如上链接,访问地址可以改成
1
| localhost:8101/cloud-provider/providerController/hello
|
与开启根据微服务名转发可以共存,互不影响。
4. 参数详解
Spring Cloud Gateway的主要功能之⼀是转发请求,转发规则的定义主要包含三个部分,如表所示。
定义 |
说明 |
Route(路由) |
路由是⽹关的基本单元,由ID、URI、⼀组Predicate、⼀组Filter组成,根据Predicate进⾏匹配转发。 |
Predicate(谓语、断⾔) |
路由转发的判断条件,⽬前SpringCloud Gateway⽀持多种⽅式,常⻅如:Path、Query、Method、Header等,写法必须遵循 key=vlue的形式 |
Filter(过滤器) |
过滤器是路由转发请求时所经过的过滤逻辑,可⽤于修改请求、响应内容 |
4.1. Predicate 断⾔条件
规则解析
快捷配置:
规则 |
示例 |
说明 |
Path |
- Path=/gate/**,/rule/** |
当请求的路径为gate、rule开头的时 生效 |
Before |
- Before=2017-01-20T17:42:47.789-07:00[Asia/Shanghai] |
在时间之前的请求生效 |
After |
- After=2017-01-20T17:42:47.789- 07:00[Asia/Shanghai] |
在时间之后的请求生效 |
Between |
- Between=2017-01-20T17:42:47.789-07:00[Asia/Shanghai],2017-01- 21T17:42:47.789-07:00[Asia/Shanghai] |
在时间段之间的生效 |
Cookie |
- Cookie=id,[0-9] |
【Cookie=cookie名, cookie值的正则表达式规则】 |
Header |
- Header=X-Request-Id, \d+ |
【Header=header名, header值的正则表达式规则】 |
Host |
- Host=www.hd123.com |
【Host=主机名(可配置多个,也可以使用通配符)】当主机名为www.hd123.com的时候生效 |
Method |
- Method=GET |
只有GET方法生效 |
Query |
- Query=name, zhangsan |
【Query=参数名,参数值】 |
完全解析:
上面其实都是简写的形式,还有完整的写法
1 2 3 4 5 6 7
| predicates: - Path=/cloud-provider/**,/cloud-provider2/** - Cookie=mycookie,mycookievalue - name: Cookie args: name: mycookie regexp: mycookievalue
|
官方说明—官网翻译
示例:
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| spring: cloud: gateway: routes: - id: after_route uri: https://example.org predicates: - Cookie=mycookie,mycookievalue - id: after_route uri: https://example.org predicates: - name: Cookie args: name: mycookie regexp: mycookievalue - id: after_route uri: https://example.org predicates: - After=2017-01-20T17:42:47.789-07:00[America/Denver] - id: before_route uri: https://example.org predicates: - Before=2017-01-20T17:42:47.789-07:00[America/Denver] - id: between_route uri: https://example.org predicates: - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver] - id: cookie_route uri: https://example.org predicates: - Cookie=chocolate, ch.p - id: header_route uri: https://example.org predicates: - Header=X-Request-Id, \d+ - id: host_route uri: https://example.org predicates: - Host=**.somehost.org,**.anotherhost.org - id: method_route uri: https://example.org predicates: - Method=GET,POST - id: path_route uri: https://example.org predicates: - Path=/red/{segment},/blue/{segment} - id: query_route uri: https://example.org predicates: - Query=green - id: query_route uri: https://example.org predicates: - Query=red, gree. - id: remoteaddr_route uri: https://example.org predicates: - RemoteAddr=192.168.1.1/24 - id: weight_high uri: https://weighthigh.org predicates: - Weight=group1, 8 - id: weight_low uri: https://weightlow.org predicates: - Weight=group1, 2
|
用到的断言器如下:

4.2. Filter
请求过滤器是gateway中强大的处理能力
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
| spring: cloud: gateway: routes: - id: add_request_header_route uri: https://example.org filters: - AddRequestHeader=X-Request-red, blue - id: add_request_header_route uri: https://example.org predicates: - Path=/red/{segment} filters: - AddRequestHeader=X-Request-Red, Blue-{segment}
- id: add_request_parameter_route uri: https://example.org filters: - AddRequestParameter=red, blue
- id: add_request_parameter_route uri: https://example.org predicates: - Host: {segment}.myhost.org filters: - AddRequestParameter=foo, bar-{segment}
- id: add_response_header_route uri: https://example.org filters: - AddResponseHeader=X-Response-Red, Blue
- id: add_response_header_route uri: https://example.org predicates: - Host: {segment}.myhost.org filters: - AddResponseHeader=foo, bar-{segment}
- id: dedupe_response_header_route uri: https://example.org filters: - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin - id: hystrix_route uri: https://example.org filters: - Hystrix=myCommandName - id: hystrix_route uri: lb://backing-service:8088 predicates: - Path=/consumingserviceendpoint filters: - name: Hystrix args: name: fallbackcmd fallbackUri: forward:/incaseoffailureusethis - RewritePath=/consumingserviceendpoint, /backingserviceendpoint - 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
- id: circuitbreaker_route uri: https://example.org filters: - CircuitBreaker=myCircuitBreaker - id: circuitbreaker_route uri: lb://backing-service:8088 predicates: - Path=/consumingServiceEndpoint filters: - name: CircuitBreaker args: name: myCircuitBreaker fallbackUri: forward:/inCaseOfFailureUseThis - RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint - id: ingredients uri: lb://ingredients predicates: - Path=//ingredients/** filters: - name: CircuitBreaker args: name: fetchIngredients fallbackUri: forward:/fallback - id: ingredients-fallback uri: http://localhost:9994 predicates: - Path=/fallback - id: ingredients uri: lb://ingredients predicates: - Path=//ingredients/** filters: - name: CircuitBreaker args: name: fetchIngredients fallbackUri: forward:/fallback - id: ingredients-fallback uri: http://localhost:9994 predicates: - Path=/fallback filters: - name: FallbackHeaders args: executionExceptionTypeHeaderName: Test-Header - id: map_request_header_route uri: https://example.org filters: - MapRequestHeader=Blue, X-Request-Red - id: prefixpath_route uri: https://example.org filters: - PrefixPath=/mypath
- id: requestratelimiter_route uri: https://example.org filters: - name: RequestRateLimiter args: redis-rate-limiter.replenishRate: 10 redis-rate-limiter.burstCapacity: 20 redis-rate-limiter.requestedTokens: 1 - id: requestratelimiter_route uri: https://example.org filters: - name: RequestRateLimiter args: rate-limiter: "#{@myRateLimiter}" key-resolver: "#{@userKeyResolver}" - id: prefixpath_route uri: https://example.org filters: - RedirectTo=302, https://acme.org
- id: removerequestheader_route uri: https://example.org filters: - RemoveRequestHeader=X-Request-Foo
- id: removeresponseheader_route uri: https://example.org filters: - RemoveResponseHeader=X-Response-Foo - id: removerequestparameter_route uri: https://example.org filters: - RemoveRequestParameter=red - id: rewritepath_route uri: https://example.org predicates: - Path=/foo/** filters: - RewritePath=/red(?<segment>/?.*), $\{segment}
- id: rewritelocationresponseheader_route uri: http://example.org filters: - RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,
- id: rewriteresponseheader_route uri: https://example.org filters: - RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***
- id: save_session uri: https://example.org predicates: - Path=/foo/** filters: - SaveSession
- id: setpath_route uri: https://example.org predicates: - Path=/red/{segment} filters: - SetPath=/{segment}
- id: setrequestheader_route uri: https://example.org filters: - SetRequestHeader=X-Request-Red, Blue - id: setrequestheader_route uri: https://example.org predicates: - Host: {segment}.myhost.org filters: - SetRequestHeader=foo, bar-{segment}
- id: setresponseheader_route uri: https://example.org filters: - SetResponseHeader=X-Response-Red, Blue - id: setresponseheader_route uri: https://example.org predicates: - Host: {segment}.myhost.org filters: - SetResponseHeader=foo, bar-{segment} - id: setstatusint_route uri: https://example.org filters: - SetStatus=401 - id: nameRoot uri: https://nameservice predicates: - Path=/name/** filters: - StripPrefix=2
- id: retry_test uri: http://localhost:8080/flakey predicates: - Host=*.retry.com filters: - name: Retry args: retries: 3 statuses: BAD_GATEWAY methods: GET,POST backoff: firstBackoff: 10ms maxBackoff: 50ms factor: 2 basedOnPreviousValue: false - id: request_size_route uri: http://localhost:8080/upload predicates: - Path=/upload filters: - name: RequestSize args: maxSize: 5000000
|
用到的过滤器如下:

除了指定具体的匹配对应的过滤器外,还可以指定全局过滤器
1 2 3 4 5 6
| spring: cloud: gateway: default-filters: - AddResponseHeader=X-Response-Default-Red, Default-Blue - PrefixPath=/httpbin
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 根据这篇博文中的建议,工厂SecureHeaders GatewayFilter在响应中添加了许多标头。
添加了以下标头(显示其默认值): 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 x-frame-options x-content-type-options referrer-policy content-security-policy x-download-options x-permitted-cross-domain-policies 要禁用默认值,请spring.cloud.gateway.filter.secure-headers.disable使用逗号分隔值设置属性。以下示例展示了如何执行此操作: spring.cloud.gateway.filter.secure-headers.disable=x-frame-options,strict-transport-security
|
4.2.2. ModifyRequestBody
修改请求体过滤器
请求传下去时修改请求体,该过滤器只能使用 Java DSL 进行配置
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
| @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; } }
|
4.2.3. ModifyRequestBody
修改响应体过滤器
1 2 3 4 5 6 7 8 9
| @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(); }
|
4.2.4. GlobalFilter
全局过滤器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @Bean public GlobalFilter customFilter() { return new CustomGlobalFilter(); }
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { log.info("custom global filter"); return chain.filter(exchange); }
@Override public int getOrder() { return -1; } }
|
从exchange中可以拿到很多东西

LoadBalancerClientFilter
负载均衡过滤器
处理配置文件中的 uri: lb://service-namae
WebsocketRoutingFilter
websoket过滤器
处理配置文件中的 uri: ws://service-namae
5. CORS跨域处理配置
1 2 3 4 5 6 7 8 9
| spring: cloud: gateway: globalcors: cors-configurations: '[/**]': allowedOrigins: "https://docs.spring.io" allowedMethods: - GET
|
官方文档google翻译:

6. 官方配置文件
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.2.RELEASE/reference/html/appendix.html
7. Actuator 配置
1 2 3 4
| management.endpoint.gateway.enabled=true
management.endpoints.web.exposure.include=gateway
|
http://localhost:8101/actuator/gateway/routes