- 引入网关
- rotue(路由)
- 10.3 Prendicate(谓词工厂)
- filter
- AddRequestHeaderGatewayFilterFactory
- AddRequestParameterGatewayFilterFactory
- AddResponseHeaderGatewayFilterFactory
- DedupeResponseHeaderGatewayFilterFactory
- PrefixPathGatewayFilterFactory
- PreserveHostHeaderGatewayFilterFactory
- RequestRateLimiterGatewayFilterFactory
- RedirectToGatewayFilterFactory
- RemoveRequestHeaderGatewayFilterFactory
- RemoveResponseHeaderGatewayFilterFactory
- RewritePathGatewayFilterFactory
- RewriteResponseHeaderGatewayFilterFactory
- SaveSessionGatewayFilterFactory
- SetPathGatewayFilterFactory
- SetResponseHeaderGatewayFilterFactory
- SetStatusGatewayFilterFactory
- StripPrefixGatewayFilterFactory
- RetryGatewayFilterFactory
- RequestSizeGatewayFilterFactory
- 自定义过滤器
- 7月23日
网关是一个Api服务器,是系统的唯一入口。为每个客户端提供一个定制的Restful API。同时它还需要具有一些业务之外的责任:鉴权。静态响应等处理。网关的最主要在作用就是路由的转发 。但是 在我们平时的使用过程中,直接请求http 协议的 api 会存在很多问题。例如:安全问题,流量问题 等等。所以gateway 还需要做一些额外的 事情来保证我们的流程是安全的、可靠的。<br />![](https://cdn.nlark.com/yuque/0/2021/png/21509632/1627092337248-4e754453-a973-4549-b3d1-e4a4a50afb76.png#align=left&display=inline&height=596&margin=%5Bobject%20Object%5D&originHeight=596&originWidth=450&size=0&status=done&style=none&width=450)<br /> 客户端向Spring Cloud Gateway发出请求。网关处理程序映射确定请求与路由匹配,则将其发送到网关Web处理程序。该处理程序通过特定于请求的过滤器链运行请求。
引入网关
导包
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
开启默认路由设置
spring: cloud: gateway: discovery: locator: enabled: true
默认路由配置的访问方式:http://网关ip:port/具体服务名/**
rotue(路由)
路由就是将不同的请求映射到不同的后端集群中,这是网关的核心功能,它由ID,目标URI,谓词集合和过滤器集合定义。
routes: - id: #定义需要路由的服务唯一标识 uri: #定义服务的访问地址,可以是当前nacos上的服务:lb://服务名,也可以上网络服务http:// filters:#定义一组过滤器 - xxx predicates: #定义一组谓词工厂 - Path=/news/**
10.3 Prendicate(谓词工厂)
After
spring: cloud: gateway: routes: - id: after_user uri: lb://user-server predicates: # 当且仅当请求时的时间After配置的时间时,才会转发到用户微服务 # 目前配置不会进该路由配置,所以返回404 # 将时间改成 < now的时间,则访问localhost:8040/** -> user-center/** # eg. 访问http://localhost:8040/users/1 -> user-center/users/1 - After=2030-01-20T17:42:47.789-07:00[America/Denver]
Before
spring: cloud: gateway: routes: - id: before_user uri: lb://user-server predicates: # 当且仅当请求时的时间Before配置的时间时,才会转发到用户微服务 # 目前配置不会进该路由配置,所以返回404 # 将时间改成 > now的时间,则访问localhost:8040/** -> user-center/** # eg. 访问http://localhost:8040/users/1 -> user-center/users/1 - Before=2018-01-20T17:42:47.789-07:00[America/Denver]
Between
spring: cloud: gateway: routes: - id: between_user uri: lb://user-server predicates: # 当且仅当请求时的时间Between配置的时间时,才会转发到用户微服务 # 因此,访问localhost:8040/** -> user-center/** # eg. 访问http://localhost:8040/users/1 -> user-center/users/1 - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2027-01-21T17:42:47.789-07:00[America/Denver]
Cookie
spring: cloud: gateway: routes: - id: cookie_user uri: lb://user-server predicates: # 当且仅当带有名为somecookie,并且值符合正则ch.p的Cookie时,才会转发到用户服务 # 如Cookie满足条件,则访问http://localhost:8040/** -> user-center/** # eg. 访问http://localhost:8040/users/1 -> user-center/users/1 - Cookie=somecookie, ch.p
Header
spring: cloud: gateway: routes: - id: header_user uri: lb://user-server predicates: # 当且仅当带有名为X-Request-Id,并且值符合正则\d+的Header时,才会转发到用户服务 # 如Header满足条件,则访问http://localhost:8040/** -> user-center/** # eg. 访问http://localhost:8040/users/1 -> user-center/users/1 - Header=X-Request-Id, \d+
Host
spring: cloud: gateway: routes: - id: host_user uri: lb://user-server predicates: # 当且仅当名为Host的Header符合**.somehost.org或**.anotherhost.org时,才会转发用户微服务 # 如Host满足条件,则访问http://localhost:8040/** -> user-center/** # eg. 访问http://localhost:8040/users/1 -> user-center/users/1 - Host=**.somehost.org,**.anotherhost.org
Method
spring: cloud: gateway: routes: - id: method_user uri: lb://user-server predicates: # 当且仅当HTTP请求方法是GET时,才会转发用户微服务 # 如请求方法满足条件,访问http://localhost:8040/** -> user-center/** # eg. 访问http://localhost:8040/users/1 -> user-center/users/1 - Method=GET
Path
spring: cloud: gateway: routes: - id: path_user uri: lb://user-server predicates: # 当且仅当访问路径是/users/*或者/some-path/**,才会转发用户微服务 # segment是一个特殊的占位符,单层路径匹配 # eg. 访问http://localhost:8040/users/1 -> user-center/users/1 - Path=/users/{segment},/some-path/**
Query
spring: cloud: gateway: routes: - id: query_user uri: lb://user-server predicates: # 当且仅当请求带有baz的参数,才会转发到用户微服务 # eg. 访问http://localhost:8040/users/1?baz=xx -> user-center的/users/1 - Query=baz
RemoteAddr
spring: cloud: gateway: routes: - id: remoteaddr_user uri: lb://user-server predicates: # 当且仅当请求IP是192.168.1.1/24网段,例如192.168.1.10,才会转发到用户微服务 # eg. 访问http://localhost:8040/users/1 -> user-center的/users/1 - RemoteAddr=192.168.1.1/24
filter
过滤器,用来在请求与相应之间做统一的逻辑处理,生命周期有两个层次,一个是请求过来可以过滤,响应回去也可以过滤,过滤器分为全局过滤器以及局部过滤器。
我们可以创建过滤器工厂来定义过滤器而方便配置AddRequestHeaderGatewayFilterFactory
spring: cloud: gateway: routes: - id: add_request_header_route uri: https://example.org filters: #为原始请求添加名为 X-Request-Foo ,值为 Bar 的请求头。 - AddRequestHeader=X-Request-Foo, Bar
AddRequestParameterGatewayFilterFactory
spring: cloud: gateway: routes: - id: add_request_parameter_route uri: https://example.org filters: #为原始请求添加请求参数 foo=bar - AddRequestParameter=foo, bar
AddResponseHeaderGatewayFilterFactory
spring: cloud: gateway: routes: - id: add_response_header_route uri: https://example.org filters: #添加名为 X-Request-Foo ,值为 Bar 的响应头。 - AddResponseHeader=X-Response-Foo, Bar
DedupeResponseHeaderGatewayFilterFactory
spring: cloud: gateway: routes: - id: dedupe_response_header_route uri: https://example.org filters: -DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin,RETAIN_FIRST
PrefixPathGatewayFilterFactory
spring: cloud: gateway: routes: - id: prefixpath_route uri: https://example.org filters: #为匹配的路由添加前缀。例如:访问${GATEWAY_URL}/hello 会转发到https://example.org/mypath/hello - PrefixPath=/mypath
PreserveHostHeaderGatewayFilterFactory
spring: cloud: gateway: routes: - id: preserve_host_route uri: https://example.org filters: #如果不设置,那么名为 Host 的Header由Http Client控制;如果设置了,那么会设置一个请求属性 #路由过滤器会检查从而去判断是否要发送原始的、名为Host的Header。 - PreserveHostHeader
RequestRateLimiterGatewayFilterFactory
spring: cloud: gateway: routes: - id: requestratelimiter_route uri: https://example.org filters: - name: RequestRateLimiter args: redis-rate-limiter.replenishRate: 10 redis-rate-limiter.burstCapacity: 20
RedirectToGatewayFilterFactory
spring: cloud: gateway: routes: - id: prefixpath_route uri: https://example.org filters: # 配置成HTTP状态码, URL的形式 - RedirectTo=302, http://www.itmuch.com
RemoveRequestHeaderGatewayFilterFactory
spring: cloud: gateway: routes: - id: removerequestheader_route uri: https://example.org filters: #为原始请求删除名为 X-Request-Foo 的请求头 - RemoveRequestHeader=X-Request-Foo
RemoveResponseHeaderGatewayFilterFactory
spring: cloud: gateway: routes: - id: removeresponseheader_route uri: https://example.org filters: #删除名为 X-Request-Foo 的响应头 - RemoveResponseHeader=X-Response-Foo
RewritePathGatewayFilterFactory
spring: cloud: gateway: routes: - id: rewritepath_route uri: https://example.org predicates: - Path=/foo/** filters: # 配置成原始路径正则, 重写后的路径的正则 - RewritePath=/foo/(?<segment>.*), /$\{segment}
重写请求路径。如上配置,访问 /foo/bar 会将路径改为/bar 再转发,也就是会转发到 https://example.org/bar 。需要注意的是,由于YAML语法,需用$\ 替换 $ 。
RewriteResponseHeaderGatewayFilterFactory
spring: cloud: gateway: routes: - id: rewriteresponseheader_route uri: https://example.org filters: - RewriteResponseHeader=X-Response-Foo, password=[^&]+, password=***
如果名为 X-Response-Foo 的响应头的内容是/42?user=ford&password=omg!what&flag=true,则会被修改为/42?user=ford&password=*&flag=true。
SaveSessionGatewayFilterFactory
spring: cloud: gateway: routes: - id: save_session uri: https://example.org predicates: - Path=/foo/** filters: - SaveSession
在转发到后端微服务请求之前,强制执行 WebSession::save 操作。用在那种像 Spring Session 延迟数据存储(笔者注:数据不是立刻持久化)的,并希望在请求转发前确保session状态保存情况。
如果你将Spring Secutiry于Spring Session集成使用,并想确保安全信息都传到下游机器,你就需要配置这个filter。SetPathGatewayFilterFactory
spring: cloud: gateway: routes: - id: setpath_route uri: https://example.org predicates: - Path=/foo/{segment} filters: - SetPath=/{segment}
采用路径template参数,通过请求路径的片段的模板化,来达到操作修改路径的母的,运行多个路径 片段模板化。
如上配置,访问${GATEWAY_PATH}/foo/bar ,则对于后端微服务的路径会修改为 /bar 。SetResponseHeaderGatewayFilterFactory
spring: cloud: gateway: routes: - id: setresponseheader_route uri: http://example.org filters: - SetResponseHeader=X-Response-Foo, Bar
如果后端服务响应带有名为 X-Response-Foo 的响应头,则将值改为替换成 Bar 。
SetStatusGatewayFilterFactory
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
修改响应的状态码,值可以是数字,也可以是字符串。但一定要是Spring HttpStatus 枚举类中的值。 如上配置,两种方式都可以返回HTTP状态码401。
StripPrefixGatewayFilterFactory
spring: cloud: gateway: routes: - id: nameRoot uri: http://nameservice predicates: - Path=/name/** filters: - StripPrefix=2
数字表示要截断的路径的数量。如上配置,如果请求的路径为 /name/bar/foo ,则路径会修改为/foo , 也就是会截断2个路径
RetryGatewayFilterFactory
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
针对不同的响应做重试,可配置如下参数:
retries: 重试次数
statuses: 需要重试的状态码,取值在 org.springframework.http.HttpStatus 中
methods: 需要重试的请求方法,取值在 org.springframework.http.HttpMethod 中
series: HTTP状态码系列,取值在 org.springframework.http.HttpStatus.Series 中RequestSizeGatewayFilterFactory
spring: cloud: gateway: routes: - id: request_size_route uri: http://localhost:8080/upload predicates: - Path=/upload filters: - name: RequestSize args: # 单位字节 maxSize: 5000000
为后端服务设置收到的最大请求包大小。如果请求大小超过设置的值,则返回 413 Payload Too Large ,默认值是5M
自定义过滤器
全局过滤器:所有的路由都生效。实现GlobalFilter接口,Ordered接口是用来规定执行顺序
@Component public class MyGlobaleFilter implements GlobalFilter ,Ordered{ @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { System.out.println("========全局拦截器==========="); return chain.filter(exchange); } @Override public int getOrder() { return 1; } }
过自定义过滤器工厂来实现局部过滤
//继承父类接口的泛型规定了参数对象类型 @Component public class AuthenticationGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthenticationGatewayFilterFactory.Config> { //构造方法对参数对象进行说明 public AuthenticationGatewayFilterFactory() { super(Config.class); } //用来指定参数的顺序,当前无 @Override public List<String> shortcutFieldOrder() { return Arrays.asList(); } //用来接收参数的类,该过滤器不需要参数 public static class Config {} //创建过滤器对象,能够从config里面获取传递的参数 @Override public GatewayFilter apply(Config config) { return (exchange,chain) -> { System.out.println(“====进入认证过滤器====”); return chain.filter(exchange); }; } }
7月23日
网关的概念以及特点
网关是一个Api服务器,是系统的唯一入口。为每个客户端提供一个定制的Restful API。同时它还需要具有一些业务之外的责任:鉴权。静态响应等处理。网关的最主要在作用就是路由的转发 。但是 在我们平时的使用过程中,直接请求http 协议的 api 会存在很多问题。例如:安全问题,流量问题 等等。所以gateway 还需要做一些额外的 事情来保证我们的流程是安全的、可靠的。
客户端向Spring Cloud Gateway发出请求。网关处理程序确定请求与路由匹配,则将其发送到网关Web处理程序。该处理程序通过特定于请求的过滤器链运行请求。
特点
- 动态路由,能够匹配任何请求属性;
- 可以对路由指定Predicate(断言)和Filter(过滤器),且易于编写;
- 集成Hystrix的断路器功能;
- 集成SpringCloud服务发现功能;
- 请求限流功能;
- 支持路径重写
- Gateway与Zuul的区别
Zuul:
使用的是阻塞式的 API,不支持长连接,比如 websockets。
底层是servlet,Zuul处理的是http请求
没有提供异步支持,流控等均由hystrix支持。
依赖包spring-cloud-starter-netflix-zuul。
Gateway:
底层依然是servlet,但使用了webflux,多嵌套了一层框架
依赖spring-boot-starter-webflux和/ spring-cloud-starter-gateway
提供了异步支持,提供了抽象负载均衡,提供了抽象流控,并默认实现了RedisRateLimiter。
3. 路由里面的谓词工厂是什么
用来指定路由规则
4. 全局过滤器与局部过滤器的区别
全局处理器:所有的路由都生效。实现GlobalFilter接口,Ordered接口是用来规定执行顺序
局部处理器extends AbstractGatewayFilterFactory
- 两种过滤器各自的实现流程
全局过滤器:所有的路由都生效。实现GlobalFilter接口,Ordered接口是用来规定执行顺序@Component public class MyGlobaleFilter implements GlobalFilter ,Ordered{ @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { System.out.println("========全局拦截器==========="); return chain.filter(exchange); } @Override public int getOrder() { return 1; } }
自定义过滤器:工厂来实现局部过滤
//继承父类接口的泛型规定了参数对象类型
@Component
public class AuthenticationGatewayFilterFactory extends
AbstractGatewayFilterFactory<AuthenticationGatewayFilterFactory.Config> {
//构造方法对参数对象进行说明
public AuthenticationGatewayFilterFactory() {
super(Config.class);
}
//用来指定参数的顺序,当前无
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList();
}
//用来接收参数的类,该过滤器不需要参数
public static class Config {}
//创建过滤器对象,能够从config里面获取传递的参数
@Override
public GatewayFilter apply(Config config) {
return (exchange,chain) -> {
System.out.println(“====进入认证过滤器====”);
return chain.filter(exchange);
};
}
}