Spring Cloud Gateway 基于 Spring Boot 2.x、Spring WebFlux和Project Reactor,WebFlux默认启动容器是Netty,在学习之前最好是做一些相关的了解。特别是WebFlux。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>org.examplegroupId>
<artifactId>myGatewayartifactId>
<version>1.0-SNAPSHOTversion>
<properties>
<build.name>myGatewaybuild.name>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<java.version>1.8java.version>
<spring.cloud.version>2021.0.4spring.cloud.version>
<spring.cloud.alibaba.version>2021.0.4.0spring.cloud.alibaba.version>
properties>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.6.11version>
parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>${spring.cloud.version}version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-gatewayartifactId>
dependency>
dependencies>
<profiles>
<profile>
<id>devid>
<properties>
<profileActive>devprofileActive>
properties>
<activation>
<activeByDefault>trueactiveByDefault>
activation>
profile>
<profile>
<id>testid>
<properties>
<profileActive>testprofileActive>
properties>
profile>
<profile>
<id>preid>
<properties>
<profileActive>preprofileActive>
properties>
profile>
<profile>
<id>prodid>
<properties>
<profileActive>prodprofileActive>
properties>
profile>
profiles>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
<finalName>${build.name}finalName>
<resources>
<resource>
<directory>src/main/resourcesdirectory>
<filtering>truefiltering>
<includes>
<include>mapper/**/*.xmlinclude>
<include>application.ymlinclude>
<include>application-${profileActive}.ymlinclude>
<include>application.propertiesinclude>
<include>application-${profileActive}.propertiesinclude>
<include>bootstrap.propertiesinclude>
<include>logback-spring.xmlinclude>
includes>
resource>
resources>
build>
project>
在pom文件中添加spring-cloud-starter-gateway依赖即可。
server:
port: 8080
spring:
cloud:
gateway:
routes:
- id: myCloud_route
uri: http://127.0.0.1:8701/myCloud
predicates:
- Path=/myCloud/**
我们的路由开发端口为8080,上下文为/
这里我们配置了一个路径断言(Predicate),所有/myCloud上下文的请求,都路由到http://127.0.0.1:8701/myCloud。路由到的地址是我们前文中的Provider 8701。
package com.yyoo.cloud.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = {"com.yyoo"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
我们的启动类没有任何的区别。
访问 http://127.0.0.1:8080/myCloud/conf/getCommonConf ,返回结果如下:
CommonConf(name=没事儿写两篇, age=12, desc=Spring Cloud 学习)8701
我们通过Gateway网关的接口访问到了我们的Provider 8701的接口。
注:以下均为官网示例
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
该路由匹配 2017 年 1 月 20 日 17:42 之后提出的任何请求。(注意时区),此配置是ZonedDateTime对象
spring:
cloud:
gateway:
routes:
- id: before_route
uri: https://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
spring:
cloud:
gateway:
routes:
- 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]
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=chocolate, ch.p
此路由匹配具有名为 chocolate的cookie,并且其值与 ch.p 正则表达式相匹配的 cookie 的请求。
spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+
意为请求头为X-Request-Id,其值满足正则表达式\d+,多个请求头添加多个predicate即可。
spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}
{segment}为占位符,断言工厂会将对应的值通过ServerWebExchange.setAttributes()放在ServerWebExchange,其key值为ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE。之后可以在GatewayFilter中使用
Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);
String segment = uriVariables.get("segment");
其他断言工厂请查看官网网关路由断言工厂
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
filters:
- AddRequestHeader=X-Request-red, blue
使用URI扩展变量
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- AddRequestHeader=X-Request-Red, Blue-{segment}
与之对应的还有,添加请求参数,添加响应头,删除请求参数、请求头,响应头等网关过滤器。
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: https://example.org
predicates:
- Path=/red/**
filters:
- RewritePath=/red/?(?>.*), /$\{segment}
对于请求路径/red/blue,会将路径设置为/blue发出下游请求之前的路径。
由于 YAML 规范,$ 被替换为。$\
此操作相当于把当前的请求uri中的/red给去掉了,这在要访问的uri上下文和我们网关访问的uri的上下午不一致时非常有用。
spring:
cloud:
gateway:
httpclient:
connect-timeout: 1000 # 连接超时
response-timeout: 5s # 响应超时(响应超时请合理设置,太短会造成多次重试)
routes:
- id: myCloud_route
uri: http://127.0.0.1:8701/myCloud
predicates:
- Path=/myCloud/**
filters:
- AddRequestHeader=X-token, blue
- name: Retry
args:
retries: 3
statuses: BAD_GATEWAY
methods: GET,POST
backoff:
firstBackoff: 10ms
maxBackoff: 50ms
factor: 2
basedOnPreviousValue: false
示例设置了连接超时和响应超时的时间设置
注:特别是响应超时的时候,其实请求是实际发送了的,只是服务端响应时间太长,导致响应超时,这就要确保我们请求的接口幂等性,否则会有重复数据出现。
其他过滤器工厂请查看官网网关路由过滤器工厂