spring cloud微服务实践七
在spring cloud 2.x以后,由于zuul一直停滞在1.x版本,所以spring官方就自己开发了一个项目 Spring Cloud Gateway
.作为spring cloud微服务的网关组件.
注:这一个系列的开发环境版本为 java1.8, spring boot2.x, spring cloud Greenwich.SR2, IDE为 Intelli IDEA
spring cloud gateway 入门
根据官方的简介,它是spring mvc基础之上,旨在提供一个简单有效的路由管理方式,如 安全,监控/指标,和限流等.
相关概念
- Route(路由):这是网关的基本构建部分。它由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配。
- Predicate(断言):这是一个 Java 8 的 Predicate。输入类型是一个 ServerWebExchange。我们可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。
- Filter(过滤器):这是
org.springframework.cloud.gateway.filter.GatewayFilter
的实例,我们可以使用它修改请求和响应。
工作流程
客户端向 Spring Cloud Gateway 发出请求。如果 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。 过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执行业务逻辑。
Spring Cloud Gateway 的特征:
- 基于 Spring Framework 5,Project Reactor 和 Spring Boot 2.0
- 动态路由
- Predicates 和 Filters 作用于特定路由
- 集成 Hystrix 断路器
- 集成 Spring Cloud DiscoveryClient
- 易于编写的 Predicates 和 Filters
- 限流
- 路径重写
注: 以上引自: http://www.ityouknow.com
简单使用
添加依赖
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
配置文件
spring cloud gateway底层使用netty+webflux, 不再依赖web了
server:
port: 8080
spring:
cloud:
gateway:
routes:
- id: iyk_route
uri: http://www.ityouknow.com
predicates:
- Path=/spring-cloud
说明下该配置:
- id:自定义的路由 ID,保持唯一
- uri:目标服务地址
- predicates:路由条件,Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)。
- filters:过滤规则
同样的,转发功能也可以使用代码来实现:
// 直接写在启动类中
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("path_route", r -> r.path("/about")
.uri("http://ityouknow.com"))
.build();
}
注: 虽然两种方法都可以,但还是建议写在配置文件中
路由规则
Spring Cloud Gateway 是通过 Spring WebFlux 的 HandlerMapping 做为底层支持来匹配到转发路由,Spring Cloud Gateway 内置了很多 Predicates 工厂,这些 Predicates 工厂通过不同的 HTTP 请求参数来匹配,多个 Predicates 工厂可以组合使用。
predicates
Predicate 来源于 Java 8,是 Java 8 中引入的一个函数,Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)。可以用于接口请求参数校验、判断新老数据是否有变化需要进行更新操作。
在 Spring Cloud Gateway 中 Spring 利用 Predicate 的特性实现了各种路由匹配规则,有通过 Header、请求参数等不同的条件来进行作为条件匹配到对应的路由。网上有一张图总结了 Spring Cloud 内置的几种 Predicate 的实现。
接下来我们就来看看这些规则的具体使用方法:
时间匹配
predicate 支持设置一个时间,以这个时间为分界线,这个时间前的不能访问,这个时间之后的可以访问.
spring:
cloud:
gateway:
routes:
- id: time_route
uri: http://example.com
predicates:
- After=2019-08-17T12:00:00+08:00[Asia/Shanghai]
Spring 是通过 ZonedDateTime 来对时间进行的对比,ZonedDateTime 是 Java 8 中日期时间功能里,用于表示带时区的日期与时间信息的类,ZonedDateTime 支持通过时区来设置时间,中国的时区是:Asia/Shanghai
。
After Route Predicate 是指在这个时间之后的请求都转发到目标地址。上面的示例是指,请求时间在 2018年1月20日6点6分6秒之后的所有请求都转发到地址http://example.com。+08:00是指时间和UTC时间相差八个小时,时间地区为Asia/Shanghai
。
添加完路由规则之后,访问地址http://localhost:8080会自动转发到http://example.com。
Before Route Predicate 刚好相反,在某个时间之前的请求的请求都进行转发。我们把上面路由规则中的 After 改为 Before,如下:
spring:
cloud:
gateway:
routes:
- id: before_route
uri: http://example.com
predicates:
- Before=2019-08-17T12:00:00+08:00[Asia/Shanghai]
既然有这个时间前After
和这个时间后Before
,predicate还支持在一段时间之内匹配,那就需要使用Between
spring:
cloud:
gateway:
routes:
- id: after_route
uri: http://example.com
predicates:
- Between=2019-08-17T08:00:00+08:00[Asia/Shanghai], 2019-08-17T09:00:00+08:00[Asia/Shanghai]
这个功能刚好可以使用在一些抢购活动中.
Cookie 匹配
Cookie Route Predicate 可以接收两个参数,一个是 Cookie name ,一个是正则表达式,路由规则会通过获取对应的 Cookie name 值和正则表达式去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行。
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: http://example.com
predicates:
- Cookie=a,b.c
这表示请求的cookie需要携带 a=b.c 才可以访问,否则就报404错误,可以使用 curl http://localhost:8080 --cookie "a=b.c"
Header 匹配
Header Route Predicate 和 Cookie Route Predicate 一样,也是接收 2 个参数,一个 header 中的属性名称和一个正则表达式,这个属性值和正则表达式匹配则执行。
spring:
cloud:
gateway:
routes:
- id: header_route
uri: http://example.com
predicates:
- Header=X-Request-Id, \d+
同样的可以使用命令url http://localhost:8080 --header "X-Request-Id:11"
来测试.
Host 匹配
Host Route Predicate 接收一组参数,一组匹配的域名列表,这个模板是一个 ant 分隔的模板,用.号作为分隔符。它通过参数中的主机地址作为匹配规则
spring:
cloud:
gateway:
routes:
- id: header_route
uri: http://example.com
predicates:
- Host=**.example.com
请求方法匹配
可以通过请求方式GET,POST,PATH和DELETE方法进行匹配:
spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET
请求路径匹配
predicate接受两个参数,一个PathMatcher
表达式 和一个可选参数 matchOptionalTrailingSeparator
spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Path=/foo/{segment},/bar/{segment}
能匹配到/foo/1
, /foo/bar
或/bar/baz
等路径。
同时也可以使用代码获取:
Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);
String segment = uriVariables.get("segment");
请求参数匹配
Query Route Predicate 支持传入两个参数,一个是属性名一个为属性值,属性值可以是正则表达式。
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=baz
ip地址匹配
RemoteAddr Route Predicate 支持匹配相应的ip地址,如(IPv4 or IPv6),或者一个网段192.168.0.1/16
,一个地址192.168.0.1
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24
权重匹配
Weight Route Predicate 接受两个参数,分组和权重:
spring:
cloud:
gateway:
routes:
- id: weight_high
uri: https://weighthigh.org
predicates:
- Weight=group1, 8
- id: weight_low
uri: https://weightlow.org
predicates:
- Weight=group1, 2
组合使用
除此之外,这些匹配还可以组合起来使用
spring:
cloud:
gateway:
routes:
- id: host_foo_path_headers_to_httpbin
uri: http://example.com
predicates:
- Host=**.foo.org
- Path=/headers
- Method=GET
- Header=X-Request-Id, \d+
- Query=foo, ba.
- Query=baz
- Cookie=chocolate, ch.p
- After=2019-08-18T12:00:00+08:00[Asia/Shanghai]
各种 Predicates 同时存在于同一个路由时,请求必须同时满足所有的条件才被这个路由匹配。
一个请求满足多个路由的谓词条件时,请求只会被首个成功匹配的路由转发
原文地址:https://www.cnblogs.com/xingyys/p/11370476.html
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 听说Mysql你很豪横?-------------MySQL5.7主从同步
- 听说Mysql你很豪横?-------------MySQL5.7主从复制!读写分离!
- Vue兄弟组件传值
- Vue设置浏览器的标题title和图标icon
- VantUI封装自定义Tabbar路由跳转
- 听说Mysql你很豪横?-------------分分钟带你玩转SQL高级查询语句(常用查询,正则表达式,运算符)
- jQuery实现点击添加样式同胞移除样式
- 微信小程序生命周期
- 听说Mysql你很豪横?-------------分分钟带你玩转SQL高级查询语句(库函数,存储过程)
- 微信小程序下拉刷新上拉加载
- 微信小程序引用自定义组件
- 听说Mysql你很豪横?-------------搭建MySQL MHA实现数据库高可用( MySQL MHA概述、 搭建 MySQL MHA、 MySQL MHA 故障切换)
- jQuery点击click()事件
- 大点干!早点散----------深入剖析LVS负载均衡群集原理
- javascript中元素的scrollLeft和scrollTop属性说明