1. 简介

Spring Cloud GateWay是Spring Cloud的一个全新项目,目标是取代Netflix Zuul,它基于 Spring5.0+SpringBoot2.0+WebFlux(基于高性能的Reactor模式响应式通信框架Netty,异步非阻塞模 型)等技术开发,性能高于Zuul,官方测试,GateWay是Zuul的1.6倍,旨在为微服务架构提供一种简 单有效的统一的API路由管理方式。
Spring Cloud GateWay不仅提供统一的路由方式(反向代理)并且基于 Filter(定义过滤器对请求过滤, 完成一些功能) 链的方式提供了网关基本的功能,例如:鉴权、流量控制、熔断、路径重写、日志监控 等。

网关在架构中的位置

2. GateWay核心概念

Zuul1.x 阻塞式IO 2.x 基于Netty
Spring Cloud GateWay天生就是异步非阻塞的,基于Reactor模型
一个请求—>网关根据一定的条件匹配—匹配成功之后可以将请求转发到指定的服务地址;而在这个过 程中,我们可以进行一些比较具体的控制(限流、日志、黑白名单)

  • 路由(route): 网关最基础的部分,也是网关比较基础的工作单元。路由由一个ID、一个目标 URL(最终路由到的地址)、一系列的断言(匹配条件判断)和Filter过滤器(精细化控制)组 成。如果断言为true,则匹配该路由。
  • 断言(predicates):参考了Java8中的断言java.util.function.Predicate,开发人员可以匹配Http 请求中的所有内容(包括请求头、请求参数等)(类似于nginx中的location匹配一样),如果断 言与请求相匹配则路由。
  • 过滤器(filter):一个标准的Spring webFilter,使用过滤器,可以在请求之前或者之后执行业务 逻辑。
    下面是一张官网的图

    其中,Predicates断言就是我们的匹配条件,而Filter就可以理解为一个无所不能的拦截器,有了 这两个元素,结合目标URL,就可以实现一个具体的路由转发。

3. GateWay工作过程

下面是来自官网的一张图,高度概述了Spring Cloud Gateway如何工作

客户端向Spring Cloud GateWay发出请求,然后在GateWay Handler Mapping中找到与请求相匹配的 路由,将其发送到GateWay Web Handler;Handler再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前 (pre)或者之后(post)执行业务逻辑。
Filter在“pre”类型过滤器中可以做参数校验、权限校验、流量监控、日志输出、协议转换等,在“post”类 型的过滤器中可以做响应内容、响应头的修改、日志的输出、流量监控等。

注意:在没有端口的路由中定义的uri对于HTTP和HTTPS uri分别获得默认端口值80和443。

4. GateWay应用

  1. 快速创建SpringBoot工程,导入依赖, GateWay不需要使用web模块,它引入的是WebFlux(类似于SpringMVC),完整的pom文件如下
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><artifactId>test-cloud-gateway</artifactId><!--spring boot 父启动器依赖--><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.6.RELEASE</version></parent><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-commons</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!--GateWay 网关--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!--引入webflux--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency><!--日志依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></dependency><!--测试依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--lombok工具--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.4</version><scope>provided</scope></dependency><!--引入Jaxb,开始--><dependency><groupId>com.sun.xml.bind</groupId><artifactId>jaxb-core</artifactId><version>2.2.11</version></dependency><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId></dependency><dependency><groupId>com.sun.xml.bind</groupId><artifactId>jaxb-impl</artifactId><version>2.2.11</version></dependency><dependency><groupId>org.glassfish.jaxb</groupId><artifactId>jaxb-runtime</artifactId><version>2.2.10-b140310.1920</version></dependency><dependency><groupId>javax.activation</groupId><artifactId>activation</artifactId><version>1.1.1</version></dependency><!--引入Jaxb,结束--><!-- Actuator可以帮助你监控和管理Spring Boot应用--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!--热部署--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency><!--链路追踪--><!--<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-sleuth</artifactId></dependency>--></dependencies><dependencyManagement><!--spring cloud依赖版本管理--><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Greenwich.RELEASE</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><!--编译插件--><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>11</source><target>11</target><encoding>utf-8</encoding></configuration></plugin><!--打包插件--><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
  1. application.yml 配置文件部分内容
server:port: 9002
eureka:client:serviceUrl:# eureka server的路径#把 eureka 集群中的所有 url 都填写了进来,也可以只写一台,因为各个 eureka server 可以同步注册表defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/instance:#使用ip注册,否则会使用主机名注册了(此处考虑到对老版本的兼容,新版本经过实验都是ip)prefer-ip-address: true#自定义实例显示格式,加上版本号,便于多版本管理,注意是ip-address,早期版本是ipAddressinstance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}:@project.version@
spring:application:name: lagou-cloud-gatewaycloud:gateway:routes: # 路由可以有多个- id: service-autodeliver-router # 我们自定义的路由 ID,保持唯一#uri: http://127.0.0.1:8096  # 目标服务地址  自动投递微服务(部署多实例)  动态路由:uri配置的应该是一个服务名称,而不应该是一个具体的服务实例的地址uri: lb://lagou-service-autodeliver # gateway网关从服务注册中心获取实例信息然后负载后路由predicates:  # 断言:路由条件,Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默 认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)。- Path=/autodeliver/**- id: service-resume-router      # 我们自定义的路由 ID,保持唯一#uri: http://127.0.0.1:8081       # 目标服务地址#http://localhost:9002/resume/openstate/1545132uri: lb://lagou-service-resumepredicates:- Path=/resume/**filters:- StripPrefix=1  # 可以去掉uri第一个位置(即resume)之后转发

5. GateWay路由规则详解

Spring Cloud GateWay帮我们内置了很多Predicates功能,实现了各种路由匹配规则(通过 Header、请求参数等作为条件)匹配到对应的路由。

  1. 时间点后匹配
 spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:- After=2017-01-20T17:42:47.789-07:00[America/Denver]
  1. 时间点前匹配
spring:cloud:gateway:routes:- id: before_routeuri: https://example.orgpredicates:- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
  1. 时间区间匹配
spring:cloud:gateway:routes:- id: between_routeuri: https://example.orgpredicates:- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
  1. 指定Cookie正则匹配指定值
spring:cloud:gateway:routes:- id: cookie_routeuri: https://example.orgpredicates:- Cookie=chocolate, ch.p
  1. 指定Header正则匹配指定值
spring:cloud:gateway:routes:- id: header_routeuri: https://example.orgpredicates:- Header=X-Request-Id, \d+
  1. 请求Host匹配指定值
spring:cloud:gateway:routes:- id: host_routeuri: https://example.orgpredicates:- Host=**.somehost.org,**.anotherhost.org
  1. 请求Method匹配指定请求方式
spring:cloud:gateway:routes:- id: method_routeuri: https://example.orgpredicates:- Method=GET,POST
  1. 请求路径正则匹配
spring:cloud:gateway:routes:- id: path_routeuri: https://example.orgpredicates:- Path=/red/{segment},/blue/{segment}
  1. 请求包含某参数
spring:cloud:gateway:routes:- id: query_routeuri: https://example.orgpredicates:- Query=green
  1. 请求包含某参数并且参数值匹配正则表达式
spring:cloud:gateway:routes:- id: query_routeuri: https://example.orgpredicates:- Query=red, gree.
  1. 远程地址匹配
spring:cloud:gateway:routes:- id: remoteaddr_routeuri: https://example.orgpredicates:- RemoteAddr=192.168.1.1/24
  1. 权重匹配
spring:cloud:gateway:routes:- id: weight_highuri: https://weighthigh.orgpredicates:- Weight=group1, 8- id: weight_lowuri: https://weightlow.orgpredicates:- Weight=group1, 2

这条路由规则将把80%的流量转发到weighthigh.org,并将20%的流量转发到weighlow.org

6. GateWay动态路由详解

GateWay支持自动从注册中心中获取服务列表并访问,即所谓的动态路由,实现步骤如下

  • pom.xml中添加注册中心客户端依赖(因为要获取注册中心服务列表,eureka客户端已经引入)
  • 动态路由配置
spring:application:name: lagou-cloud-gatewaycloud:gateway:routes: # 路由可以有多个- id: service-autodeliver-router # 我们自定义的路由 ID,保持唯一#uri: http://127.0.0.1:8096  # 目标服务地址  自动投递微服务(部署多实例)  动态路由:uri配置的应该是一个服务名称,而不应该是一个具体的服务实例的地址uri: lb://lagou-service-autodeliver # gateway网关从服务注册中心获取实例信息然后负载后路由predicates:  # 断言:路由条件,Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默 认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)。- Path=/autodeliver/**- id: service-resume-router      # 我们自定义的路由 ID,保持唯一#uri: http://127.0.0.1:8081       # 目标服务地址#http://localhost:9002/resume/openstate/1545132# 动态路由配置uri: lb://lagou-service-resumepredicates:- Path=/resume/**filters:- StripPrefix=1

注意:动态路由设置时,uri以 lb: //开头(lb代表从注册中心获取服务),后面是需要转发到的服务名称

7. GateWay过滤器

从过滤器生命周期(影响时机点)的⻆度来说,主要有两个pre和post:

  • pre:这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中 选择 请求的微服务、记录调试信息等。
  • post:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的 HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。

从过滤器类型的⻆度,Spring Cloud GateWay的过滤器分为GateWayFilter和GlobalFilter两种

  • GateWayFilter:应用到单个路由路由上
  • GlobalFilter:应用到所有的路由上
spring:cloud:gateway:routes:- id: add_request_header_routeuri: https://example.orgfilters:- AddRequestHeader=X-Request-red, blue

过滤器方式比较多,详细可以参考官网:
https://docs.spring.io/spring-cloud-gateway/docs/3.0.0-SNAPSHOT/reference/html/#gatewayfilter-factories

GlobalFilter全局过滤器是使用比较多的过滤器,下面示范一个自定义全局过滤器
需求:自定义全局过滤器实现IP访问限制

/*** 定义全局过滤器,会对所有路由生效*/
@Slf4j
@Component  // 让容器扫描到,等同于注册了
public class BlackListFilter implements GlobalFilter, Ordered {// 模拟黑名单(实际可以去数据库或者redis中查询)private static List<String> blackList = new ArrayList<>();static {blackList.add("0:0:0:0:0:0:0:1");  // 模拟本机地址}/*** 过滤器核心方法* @param exchange 封装了request和response对象的上下文* @param chain 网关过滤器链(包含全局过滤器和单路由过滤器)* @return*/@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 思路:获取客户端ip,判断是否在黑名单中,在的话就拒绝访问,不在的话就放行// 从上下文中取出request和response对象ServerHttpRequest request = exchange.getRequest();ServerHttpResponse response = exchange.getResponse();// 从request对象中获取客户端ipString clientIp = request.getRemoteAddress().getHostString();// 拿着clientIp去黑名单中查询,存在的话就决绝访问if(blackList.contains(clientIp)) {// 决绝访问,返回response.setStatusCode(HttpStatus.UNAUTHORIZED); // 状态码log.debug("=====>IP:" + clientIp + " 在黑名单中,将被拒绝访问!");String data = "Request be denied!";DataBuffer wrap = response.bufferFactory().wrap(data.getBytes());return response.writeWith(Mono.just(wrap));}// 合法请求,放行,执行后续的过滤器return chain.filter(exchange);}/*** 返回值表示当前过滤器的顺序(优先级),数值越小,优先级越高* @return*/@Overridepublic int getOrder() {return 0;}
}

8. GateWay高可用

网关作为非常核心的一个部件,如果挂掉,那么所有请求都可能无法路由处理,因此我们需要做GateWay的高可用。

GateWay的高可用很简单:可以启动多个GateWay实例来实现高可用,在GateWay的上游使用Nginx等负载均衡设备进行负载转发以达到高可用的目的。

启动多个GateWay实例(假如说两个,一个端口9002,一个端口9003),剩下的就是使用Nginx等完 成负载代理即可。示例如下:

 #配置多个GateWay实例 upstream gateway {server 127.0.0.1:9002;
server 127.0.0.1:9003; }
location / {proxy_pass http://gateway;
}

GateWay简介及使用相关推荐

  1. SpringCloud(五)- GateWay简介及GlobalFilter 过滤器的使用

    唯能极于情,故能极于剑 本文转载于:http://www.codecow.cn/ 此文由四部分组成(GateWay简介.GlobalFilter过滤器 使用.实操.debug测试.总结),别着急,慢慢 ...

  2. 统一网关GateWay简介

    文章目录 1 GateWay简介 2 搭建网关服务 2.1 创建新的module,引入依赖 2.2 编写路由配置及nacos地址 3 路由断言工厂 4 路由过滤器GatewayFilter 5 过滤器 ...

  3. API Gateway简介

    API Gateway,服务网关Chris Richardson 微服务系列 使用API网关构建微服务http://blog.daocloud.io/microservices-2/「Chris Ri ...

  4. 有什么办法动态更改yml的值吗_基于Redis实现Spring Cloud Gateway的动态管理

    转载本文需注明出处:微信公众号EAWorld,违者必究. 引言: Spring Cloud Gateway是当前使用非常广泛的一种API网关.它本身能力并不能完全满足企业对网关的期望,人们希望它可以提 ...

  5. 网关 Spring Cloud Gateway

    一. Gateway 简介 Spring Cloud Gateway 是Spring Cloud团队的一个全新项目,基于Spring 5.0.SpringBoot2.0.Project Reactor ...

  6. SpringCloud 微服务网关Gateway介绍及简单路由配置

    概述:什么是微服务网关?为了解决用户客户端在调用微服务系统中的多个消费者工程接口时,需要维护非常多的消费者应用接口地址等信息,以及可能存在不同应用见的调用跨域等问题,微服务网关组件随即出现.网关作为用 ...

  7. 安全研究员警告:特斯拉 Backup Gateway 联网存在多种安全风险

     聚焦源代码安全,网罗国内外最新资讯! 编译:奇安信代码卫士团队 研究人员从特斯拉 Backup Gateway(备份网关系统)中发现了多个安全弱点,并说明了它们可遭利用的方式. 周二,Rapid7 ...

  8. 青柠开车Spring Cloud(六) —— Spring Cloud Gateway与zuul使用对比

    青柠开车Spring cloud(一) -- 生态系统以及在企业项目中的基础架构图     (1-7),有时间可以看看 项目源码github地址 补充 Gateway简介 快速入门 Gateway 项 ...

  9. SpringCloud学习笔记(八)Gateway 网关

    目录 一.Gateway简介 1.官网 2.是什么 3.能干嘛 4.有Zuul了怎么又出来了gateway 5.Gateway特征 6.SpringCloudGateway与Zuul的区别: 7.Zu ...

最新文章

  1. 北斗导航 | 北斗卫星导航信号串行捕获算法MATLAB仿真(附源代码)
  2. c++ cout头文件_C/C++知识分享:C++常用内置函数你会几个,使用过几次呢?
  3. 从centos7默认安装的/home中转移至根目录/ (LVM操作简明教程)
  4. Python的列表List常见操作
  5. Atitit.异常处理 嵌套  冗长的解决方案
  6. 书评:Mockito Essentials
  7. 计算机网络中对等层,【计算机网络】两个网络模型——OSI参考模型和TCP/IP模型...
  8. verp中joint的type、模式的区别
  9. Python实现快乐的数字
  10. CCF 2022:DPU评测技术白皮书发布【附白皮书下载】
  11. 概率分布F(x)和概率密度f(x)
  12. SoapUI导出响应文件
  13. 常用CASE工具介绍 (csnd.net)
  14. ati jti jwt 和_JWT jti和kid属性的说明
  15. 《TCP/IP详解卷1:协议》——第2章:链路层(转载)
  16. word、pdf等格式文件下载
  17. Blender Rigify版Beefy绑定下载
  18. Error updating changes: Out of memory, malloc failed (tried to allocate 1048576 bytes)
  19. 什么是ERP?电商ERP和传统ERP到底有什么不同?
  20. (arxiv-2018) 重新审视基于视频的 Person ReID 的时间建模

热门文章

  1. 应用程序在后台运行,在后台执行startActivity后会强制把界面带到前端解决方案...
  2. python练习, 打鱼晒网问题
  3. AD转换器输入之前为何要接一个电压跟随器?
  4. MMDetection(三):公开数据集上测试和训练模型
  5. 游戏服务器主程白皮书-序言
  6. 抖音企业号建议做吗?有什么好处?
  7. Docker快速入门,看这个就够了
  8. 二十几岁的女孩应该有这几点思想
  9. flutter的Toast
  10. Android 10.0 蓝牙去掉传输文件的功能