springcloud 网关组件之gateway 实战使用:统一访问地址,经过gateway 路由到不同的微服务;过滤、断言、路由的作用;
SpringCloud官方,对SpringCloud Gateway 特征介绍如下:
(1)基于 Spring Framework 5,Project Reactor 和 Spring Boot 2.0
(2)集成 Hystrix 断路器
(3)集成 Spring Cloud DiscoveryClient
(4)Predicates 和 Filters 作用于特定路由,易于编写的 Predicates 和 Filters
(5)具备一些网关的高级功能:动态路由、限流、路径重写
从以上的特征来说,和Zuul的特征差别不大。SpringCloud Gateway和Zuul主要的区别,还是在底层的通信框架上。
简单说明一下上文中的三个术语:
**1)Filter(过滤器)**:
和Zuul的过滤器在概念上类似,可以使用它拦截和修改请求,并且对上游的响应,进行二次处理。过滤器为org.springframework.cloud.gateway.filter.GatewayFilter类的实例。
**2)Route(路由)**:
网关配置的基本组成模块,和Zuul的路由配置模块类似。一个Route模块由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配,目标URI会被访问。
**3)Predicate(断言)**:
这是一个 Java 8 的 Predicate,可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。断言的输入类型是一个 ServerWebExchange。
一、网关微服务项目搭建流程:
1、去spingcloud 官网查找配置:https://spring.io/ ,进来后点击springcloud
2、往下翻找到 gateway 组件:
3、点击进入:
4、点击 LEARN :
5、点击 Reference Doc 这里主要讲解 gateway 的使用注意事项:同时左边的目录是使用的测试demo,大家可以试着测试一下
6、其意思是:构建gateway 微服务 不能初始化再 servlet 容器,应该在netty容器:即不能引入 web 容器jar :
//不能引入此 jar
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
正常需要引入的 jar ,如下:
<!-- 必须要引入的 gateway组件 jar-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--下面三个非必须引入,根据实际情况选择,一个redis 和两个nacos 包含的配置中心、注册中心jar包 ,此次实战我们引用-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
7、gateway 的配置文件如下:
server:
#端口
port: 8016
spring:
cloud:
gateway:
#gateway的服务发现
discovery:
locator:
# 根据注册中心自动注册路由,默认false 重启生效。是否与服务发现组件进行结合,通过 serviceId 转发到具体的服务实例。默认为false,设为true便开启通过服务中心的自动根据 serviceId 创建路由的功能。
enabled: true
#开始小写转换,重启生效。是将请求路径上的服务名配置为小写(因为服务注册的时候,向注册中心注册时将服务名转成大写的了),比如以/service-hi/*的请求路径被路由转发到服务名为service-hi的服务上。
lowerCaseServiceId: true
# 跨域配置:网关系统跨域操作
globalcors:
corsConfigurations:
'[/**]': # 匹配所有请求
allowedHeaders: "*"
allowedOrigins: "*" #跨域处理 允许所有的域
# 支持的方法 允许哪些请求跨域
allowedMethods:
- GET
- POST
- DELETE
- PUT
- OPTION
#路由断言配置
routes:
#此路由的唯一标识
- id: after_route
uri: https://www.baidu.com/
#断言如果时间在 2020-05-07T19:52:47.789+08:00 之后,就访问 https://www.baidu.com/
predicates:
- After=2020-05-07T19:52:47.789+08:00
# - id: nandao-demo
# uri: lb://NANDAO-DEMO/
# predicates:
# - Path=/nandao-demo/**
# - Header=TOKEN
# - id: version
# uri: lb://VERSION
# predicates:
# - Path=/version/**
refresh:
refreshable: none
8、此网关启动后注册到nacos,端口号8016,此时启动一个客户端,端口号:8030,服务名称为,nandao-user;此客户端有个登录接口;正确情况下(不经过网关访问),调用的url为:http://localhost:8030/user/doLogin ; 如果经过网关调用的话,url 为 http://localhost:8016/nandao-user/user/doLogin ,使用很简单。注意:通过网关访问时 变成了网关的ip、同时url里加上了微服务的名称。
二、网关主要功能的测试:
1、测试网关的断言,仅仅启动gateway服务就行,配置如 下经有,
server:
port: 8000
spring:
application:
name: register-gateway-8000
cloud:
gateway:
routes:
- id: after_route
uri: https://www.baidu.com
predicates:
- After=2020-05-07T19:52:47.789+08:00
2、启动后访问url :http://localhost:8000 ,自动跳到百度页面
3,类似的还有:
#在什么时间之前
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
#在两个时间之间
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
4、如果没有找到相应断言,出现空页面:比如:
- After=2022-05-07T19:52:47.789+08:00
5,、当然可以同时配置多个断言,但是id 不能重复:
server:
port: 8000
spring:
application:
name: register-gateway-8000
cloud:
gateway:
routes:
- id: before_route
uri: https://blog.csdn.net
predicates:
- Before=2021-05-07T19:52:47.789+08:00
- id: after_route
uri: https://www.baidu.com
predicates:
- After=2022-05-07T19:52:47.789+08:00
6、cookie的断言测试:
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
#chocolate代表key , ch.p代表 value 中间用逗号隔开
- Cookie=chocolate, ch.p
测试核心代码:
public static void get() throws IOException {
HttpClient httpClient = new HttpClient();
//PostMethod postMethod= new PostMethod("http://localhost:8000/index");
GetMethod getMethod = new GetMethod("http://localhost:8000");
getMethod.addRequestHeader("Cookie","chocolate=ch.p");
int statusCode = httpClient.executeMethod(getMethod);
byte[] responseBody = getMethod.getResponseBody();
String response = new String(responseBody, "utf-8");
System.out.println("-----------response:" + response);
}
执行结果成功。
7、断言 Path 的测试 :
spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}
请求地址:http://localhost:8000/red/xxxxx ,同时 https://example.org 个服务有接口名为 red/xxxxx 的接口,就能顺利访问通。
8、举例:
server:
port: 8000
spring:
application:
name: register-gateway-8000
cloud:
gateway:
routes:
- id: path_route_1
#此服务有个接口url为:http://localhost:8030/uas/doLogin?parameter=%7B%22orgId%22:%22Navinfo%22,%22userName%22:%22admin%22,%22pwd%22:%22123456%22%7D
uri: http://localhost:8030
predicates:
- Path=/uas/{segment}
9、gateway的负载均衡,官网查询:
spring:
cloud:
gateway:
routes:
- id: hystrix_route
# lb 是loadbalance 负载均衡的简写 ,即在此服务负载,是ribbon的替代品
uri: lb://backing-service:8088
predicates:
# 此处为负载均衡的 断言条件
- Path=/consumingserviceendpoint
filters:
- name: Hystrix
args:
name: fallbackcmd
fallbackUri: forward:/incaseoffailureusethis
- RewritePath=/consumingserviceendpoint, /backingserviceendpoint
总之,断言是为了更好的路由!今天的实战分析到此,下篇我们分析其健全、限流、过滤器等功能,敬请期待!