GateWay高级特性之Predicate
# GateWay高级特性之Predicate
# 微服务名
在之前的入手案例中,配置文件中的路由有一个很大的问题,编码是写死的。
gateway:
routes:
- id: pay_routh1 #pay_routh1 #路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名
uri: http://localhost:9001 #匹配后提供服务的路由地址
predicates:
- Path=/pay/gateway/get/**
2
3
4
5
6
如果微服务地址更换,岂不是要重新换编写。
为了解决这种问题,GateWay也提供了通过微服务名
进行映射的方案。
gateway:
routes:
- id: pay_routh1 #pay_routh1 #路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名
# uri: http://localhost:9001 #匹配后提供服务的路由地址
uri: lb://nacos-producer
predicates:
- Path=/pay/gateway/get/** # 断言,路径相匹配的进行路由
2
3
4
5
6
7
这里需要注意的是,如果你使用了lb,也就是负载均衡的方式,那么请确保你GateWay服务的pom文件引入了对应架包
<!--loadbalancer-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
2
3
4
5
#
ReactiveLoadBalancerClientFilter
The
ReactiveLoadBalancerClientFilter
looks for a URI in the exchange attribute namedServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR
. If the URL has alb
scheme (such aslb://myservice
), it uses the Spring CloudReactorLoadBalancer
to resolve the name (myservice
in this example) to an actual host and port and replaces the URI in the same attribute. The unmodified original URL is appended to the list in theServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR
attribute. The filter also looks in theServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR
attribute to see if it equalslb
. If so, the same rules apply. The following listing configures aReactiveLoadBalancerClientFilter
以上是官网说明,说了如果还使用了负载均衡,则可以加上
lb:
这个前缀
当然,你没使用负载均衡不加也是ok的,到此,GateWay通过服务动态名映射网址——结束。
接下来你可以随意更换ip,或者端口来测试这种方式是否可以行。
# Mac额外
如果用非负载均衡的方式使用,mac系电脑,特别是M芯片的,还可能出现以下错误;
Unable to load io.netty.resolver.dns.macos.MacOSDnsServerAddressStreamProvider, fallback to system defaults. This may result in incorrect DNS resolutions on MacOS. Check whether you have a dependency on 'io.netty:netty-resolver-dns-native-macos'. Use DEBUG level to see the full stack: java.lang.UnsatisfiedLinkError: failed to load the required native library
这里是因为系统相冲,导致的DNS无法解析,解决方法自行百度,或者使用负载均衡的方式访问。
# Predicate相关
- https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway/configuring-route-predicate-factories-and-filter-factories.html
- https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway/request-predicates-factories.html
- Predicate: This is a Java 8 Function Predicate (opens new window). The input type is a Spring Framework
ServerWebExchange
(opens new window). This lets you match on anything from the HTTP request, such as headers or parameters.以上为官网原文,说到 Java8 函数式接口,Predicate应该大概能猜到它的作用吧,没有就是一个判断条件,符合就通过,失败就禁止。
以下就演示几个,其余的还请到官网自行查阅:
# After
The After
route predicate factory takes one parameter, a datetime
(which is a java ZonedDateTime
). This predicate matches requests that happen after the specified datetime. The following example configures an after route predicate:
gateway:
routes:
- id: pay_routh1 #pay_routh1
uri: lb://nacos-producer
predicates:
- Path=/pay/gateway/info/** # 断言,路径相匹配的进行路由
- After=2024-11-07T21:19:18.183989+08:00[Asia/Shanghai]
2
3
4
5
6
7
这样配置后,允许任何这个时间之后的请求,之前的都不允许访问
当然还有一个Before
的属性,作用呢,是允许时间节点之前的请求进入。
spring:
cloud:
gateway:
routes:
- id: before_route
uri: https://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
2
3
4
5
6
7
8
# Between
还有一个between属性,作用呢,可以猜到,允许这个时间区间的进行访问。
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]
2
3
4
5
6
7
8
This route matches any request made after Jan 20, 2017 17:42 Mountain Time (Denver) and before Jan 21, 2017 17:42 Mountain Time (Denver). This could be useful for maintenance windows.
# 总结
以上三个属性对于定时开始抢东西之类的活动很有效。
# Other
除了以上三个,还有其他的比如:Cookie
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=chocolate, ch.p
2
3
4
5
6
7
8
必须含有cookie,且名称为chocolate ,值为ch.p
Header、Host,这2个参数在官网文档中都有对应讲解。或者说自定义参数Query
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=green
# - Query=username, \d+ # 要有参数名username并且值还要是整数才能路由
2
3
4
5
6
7
8
9
只有带有对应参数才可以访问,http://localhost:9527/pay/gateway/get/3?green=123
还有指定请求方法,类型的,Method
spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST
2
3
4
5
6
7
8
只允许get,post请求才行。
还有指定域名的,RemoteAddr
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24
2
3
4
5
6
7
8
# 自定义Predicate
当然如果以上Predicate属性都无法满足你,官网还允许开发者们自行定义Predicate。
自定义Predicate属性-官网 (opens new window)
- https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway/developer-guide.html#writing-custom-route-predicate-factories
官网都是英文,所以亲爱的程序员伙伴,努力学习英文是进一步提高自身编程技术的方式之一。
当然,你也可以通过翻译软件来实现掌握自定义Predicate。