SpringCloud升级之路2020.0.x版-41. SpringCloudGateway 基本流程讲解(1)

SpringCloud升级之路2020.0.x版-41. SpringCloudGateway 基本流程讲解(1)

本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent

接下来,将进入我们升级之路的又一大模块,即网关模块。网关模块我们废弃了已经进入维护状态的 zuul,选用了 Spring Cloud Gateway 作为内部网关。为何选择 Spring Cloud Gateway 而不是 nginx 还有 Kong 的原因是:

项目组对于 Java 更加熟悉,并且对于 Project Reactor 异步编程也比较熟悉,这个比较重要

需要在网关中使用我们之前实现的基于请求的有状态重试的压力敏感的负载均衡器

需要在网关中实现重试

需要在网关中实现实例路径断路

需要在网关中进行业务统一加解密

需要在网关中实现 BFF(Backends For Frontends)接口,即根据客户端请求,将某几个不同接口的请求一次性组合返回

需要在网关中使用 Redis 记录一些与 Token 相关的值

因此,我们使用了 Spring Cloud Gateway 作为内部网关,接下来,我们就来依次实现上面说的这些功能。同时在本次升级使用过程中, Spring Cloud Gateway 也有一些坑,例如:

结合使用 spring-cloud-sleuth 会有链路信息追踪,但是某些情况链路信息会丢失

对于三方 Reactor 封装的异步 API (例如前面提到的操作 Redis 使用的 spring-data-redis)理解不到位导致关键线程被占用

但是首先,我们需要简单理解下 Spring Cloud Gateway 究竟包括哪些组件以及整个调用流程是什么样子的。由于 Spring Cloud Gateway 基于 Spring-Boot 和 Spring-Webflux 实现,所以我们会从外层 WebFilter 开始说明,然后分析如何走到 Spring Cloud Gateway 的封装逻辑,以及 Spring Cloud Gateway 包含的组件,请求是如何转发出去,回来后又经过了哪些处理,这些我们都会逐一分析。

创建一个简单的 API 网关

为了详细分析流程,我们先来创建一个简单的网关,用于快速上手并分析。

首先创建依赖:

pom.xml

<?xml version="1.0" encoding="UTF-8"?> <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 "> <parent> <artifactId>spring-cloud-parent</artifactId> <groupId>com.github.jojotech</groupId> <version>2020.0.3-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-cloud-api-gateway</artifactId> <dependencies> <dependency> <groupId>com.github.jojotech</groupId> <artifactId>spring-cloud-webflux</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> </dependencies> </project>

parent 指向了我们项目的 spring-cloud-parent,同时加入了上一节实现的 spring-cloud-webflux 依赖,同时还需要加入 spring-cloud-starter-gateway,由于在我们的 spring-cloud-parent 已经指定了 spring-cloud-parent 的版本依赖管理,所以这里不需要指定 spring-cloud-starter-gateway 的版本

然后,我们开始编写配置文件:

application.yml

server: ##端口为 8181 port: 8181 spring: application: # 微服务名称是 apiGateway name: apiGateway cloud: gateway: httpclient: # 网关转发到其他微服务的 HTTP 连接超时为 500ms connect-timeout: 500 # 网关转发到其他微服务的 HTTP 响应超时为 500ms response-timeout: 60000 routes: # 编写转发规则 - id: first_route # 转发到微服务 test-service uri: lb://test-service # 包含哪些路径 predicates: - Path=http://www.likecs.com/test-ss/** # 转发到的微服务访问路径,去掉路径中的第一块,即去掉 /test-ss filters: - StripPrefix=1 loadbalancer: # 指定 zone,因为我们之前在负载均衡中加入了只有同一个 zone 的实例才能互相访问的逻辑 zone: test ribbon: # 关闭ribbon enabled: false cache: # 本地微服务实例列表缓存时间 ttl: 5 # 缓存大小,你的微服务调用多少个其他微服务,大小就设置为多少,默认256 capacity: 256 discovery: client: simple: # 使用 spring-common 中的简单 DiscoveryClient 服务发现客户端,就是将微服务实例写死在配置文件中 instances: # 指定微服务 test-service 的实例列表 test-service: - host: httpbin.org port: 80 metadata: # 指定该实例的 zone,因为我们之前在负载均衡中加入了只有同一个 zone 的实例才能互相访问的逻辑 zone: test eureka: client: # 关掉 eureka enabled: false

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgjfyf.html