系列十、Spring Cloud Gateway

一、Spring Cloud Gateway

1.1、概述

        Spring Cloud全家桶中有个很重要的组件就是网关,在1.x版本中采用的是Zuul网关,但是在2.x版本中,由于Zuul的升级一直跳票,Spring Cloud最后自己研发了一个网关替代Zuul,即:Spring Cloud Gateway。简单点讲Gateway就是原Zuul1.x版的替代品。

1.2、 Zuul1.x官网

https://github.com/Netflix/zuul/wiki

1.3、Gateway官网

https://spring.io/projects/spring-cloud-gateway/#overview

1.4、Gateway源码架构

1.5、已经有了Zuul为什么又出现了Gateway

(一)neflix不太靠谱,zuul2.0一直跳票,迟迟不发布;

         一方面因为Zuul1.0已经进入了维护阶段,而Gateway是Spring Cloud团队研发的,是亲儿子产品,值得信赖。而且很多功能Zuul都没有Gateway使用起来简单便捷,Gateway是基于异步非阻塞模型上进行开发的,性能方面不需要担心。虽然Netflix早就发布了最新的 Zuul 2.x,但 Spring Cloud 貌似没有整合计划。而且Netflix相关组件都宣布进入维护期;不知前景如何?
 多方面综合考虑Gateway是很理想的网关选择。

(二)Spring Cloud Gateway具有如下特性:

        (1)基于Spring Framework 6, Project Reactor 和 Spring Boot 3.0 进行构建;
        (2)动态路由:能够匹配任何请求属性;
        (3)可以对路由指定 Predicate(断言)和 Filter(过滤器);
        (4)集成Hystrix的断路器功能;
        (5)集成 Spring Cloud 服务发现功能;
        (6)易于编写的 Predicate(断言)和 Filter(过滤器);
        (7)请求限流功能;
        (8)支持路径重写。

(三)Spring Cloud Gateway 与 Zuul的区别:

        在SpringCloud Finchley 正式版之前,Spring Cloud 推荐的网关是 Netflix 提供的Zuul:
        (1)Zuul 1.x,是一个基于阻塞 I/ O 的 API Gateway;
        (2)Zuul 1.x 基于Servlet 2. 5使用阻塞架构,它不支持任何长连接(如 WebSocket) ,Zuul 的设计模式和Nginx较像,每次 I/ O 操作都是从工作线程中选择一个执行,请求线程被阻塞到工作线程完成,但是差别是Nginx 用C++ 实现,Zuul 用 Java 实现,而 JVM 本身会有第一次加载较慢的情况,使得Zuul 的性能相对较差;
        (3)Zuul 2.x理念更先进,想基于Netty非阻塞和支持长连接,但Spring Cloud目前还没有整合。 Zuul 2.x的性能较 Zuul 1.x 有较大提升。在性能方面,根据官方提供的基准测试, Spring Cloud Gateway 的 RPS(每秒请求数)是Zuul 的 1. 6 倍。
        (4)Spring Cloud Gateway 建立 在 Spring Framework 5、 Project Reactor 和 Spring Boot 2 之上, 使用非阻塞 API;

1.6、常用功能

        反向代理、鉴权、流量控制、熔断、日志监控...

1.7、微服务架构中网关的位置

1.8、三大核心概念

1.8.1、路由(Route)

        路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由。

1.8.2、断言(Predicate)

        断言参考的是Java8的java.util.function.Predicate,开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由。

1.8.3、过滤器(Filter)

指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。

1.9、工作流程

1.9.1、核心逻辑

        路由转发 + 执行过滤器链

1.9.2、工作流程

官网:How It Works :: Spring Cloud Gateway

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

1.10、断言工厂配置(Route Predicate Factories)

1.10.1、概述

        当请求Gateway的时候,使用断言对请求进行匹配,如果匹配成功就路由转发,如果匹配失败就返回404。Spring Cloud中的Gateway分为两大类,即:内置的自定义的,下面详细介绍!

官网:Route Predicate Factories :: Spring Cloud Gateway

1.10.2、(内置)基于Datetime类型的断言工厂

        Datetime类型的断言工厂用于断言时间,断言为真则路由,否则404,主要有3个,如下:

注意事项:这里的时间是带时区的时间,可以通过ZonedDateTime.now()获取

        

案例:

        

1.10.3、(内置)基于远程地址的断言工厂

案例:

       

1.10.4、(内置)基于Cookie的断言工厂

案例:

       

1.10.5、(内置)基于Header的断言工厂

案例:

       

1.10.6、(内置)基于Host的断言工厂

案例:

        

1.10.7、(内置)基于Method请求方法的断言工厂

案例:

        

1.10.8、(内置)基于Path请求路径的断言工厂

案例:

        

1.10.9、(内置)基于Query请求参数的断言工厂

案例:

        

        

1.10.10、(内置)基于路由权重的断言工厂

案例:

        

1.10.11、(自定义)基于权限的断言工厂

概述:

        上述内置的断言工厂已经能够满足我们日常工作的绝大部分场景,但是当内置的断言工厂不满足我们的需求时,那么我们可以通过自定义断言工厂的方式进行扩展,具体过程如下:

自定义断言工厂的步骤:

        (1)创建一个类并纳入Spring管理,添加@Component注解;

        (2)类必须以RoutePredicateFactory作为结尾,约定大于配置!

        (3)类必须继承自AbstractRoutePredicateFactory;

        (4)必须声明静态内部类、声明属性来接收配置文件中对应的断言信息;

        (5)结合shortcutFieldOrder进行绑定;

        (6)通过apply方法进行逻辑判断,如果为true则匹配成功,否则匹配失败;

/*** @Author : 一叶浮萍归大海* @Date: 2024/1/4 9:38* @Description: 自定义断言工厂* 功能:校验用户的权限,如果用户是已授权用户则放行,否则失败!*/
@Component
public class AuthRoutePredicateFactory extends AbstractRoutePredicateFactory<AuthRoutePredicateFactory.Config> {public static final String AUTHED_USER = "admin";public AuthRoutePredicateFactory() {super(AuthRoutePredicateFactory.Config.class);}public List<String> shortcutFieldOrder() {return Collections.singletonList("name");}public Predicate<ServerWebExchange> apply(final AuthRoutePredicateFactory.Config config) {return new GatewayPredicate() {public boolean test(ServerWebExchange serverWebExchange) {if (AUTHED_USER.equals(config.getName())) {return true;}return false;}};}@Data@AllArgsConstructor@NoArgsConstructor@Validatedpublic static class Config {private String name;}}

1.11、过滤器工厂配置(局部)

1.11.1、内置

https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway/gatewayfilter-factories.html

1.11.2、自定义

概述:

        1.7.1官网提供的内置过滤器已经能够满足我们日常工作的绝大部分场景,但是当内置的过滤器不满足我们的需求时,那么我们可以通过自定义过滤器的方式进行扩展,具体过程如下:

自定义过滤器的步骤:

        (1)创建一个类并纳入Spring管理,添加@Component注解;

        (2)类必须以GatewayFilterFactory作为结尾,约定大于配置!

        (3)类必须继承自AbstractGatewayFilterFactory;

        (4)必须声明静态内部类、声明属性来接收配置文件中对应的断言信息;

        (5)结合shortcutFieldOrder进行绑定;

        (6)通过apply方法进行逻辑判断,如果为true则匹配成功,否则匹配失败;

/*** @Author : 一叶浮萍归大海* @Date: 2024/1/4 10:28* @Description: 自定义过滤器*/
@Component
public class AuthGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthGatewayFilterFactory.Config> {public AuthGatewayFilterFactory() {super(AuthGatewayFilterFactory.Config.class);}public List<String> shortcutFieldOrder() {return Arrays.asList("value");}public GatewayFilter apply(final AuthGatewayFilterFactory.Config config) {return new GatewayFilter(){@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {/*** (1)name参数为空:成功* (2)name参数不为空:获取name参数,值不等于value就失败,否则成功*/String name = exchange.getRequest().getQueryParams().getFirst("name");if (StringUtils.isNotBlank(name)) {if (name.equals(config.getValue())) {return chain.filter(exchange);} else {exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);return exchange.getResponse().setComplete();}}return chain.filter(exchange);}};}@Data@AllArgsConstructor@NoArgsConstructorpublic static class Config {private String value;}
}

 

1.12、全局过滤器(Global Filter)配置

1.12.1、概览

1.12.2、局部过滤器 vs 全局过滤器

局部过滤器:针对某个路由,需要在路由中进行配置

全局过滤器:针对所有路由请求,一旦定义就会投入使用,无需配置

GlobalFilter和GatewayFilter有着一样的定义,只不过前者会作用于所有的路由;

1.13、统一处理跨域

1.13.1、官网(配置方式)

https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway/cors-configuration.html

1.13.2、代码方式

/*** @Author : 一叶浮萍归大海* @Date: 2024/1/4 12:53* @Description:*/
@Configuration
public class MyCorsConfig {@Beanpublic CorsWebFilter corsWebFilter() {CorsConfiguration corsConfiguration = new CorsConfiguration();corsConfiguration.addAllowedMethod("*");corsConfiguration.addAllowedOrigin("*");corsConfiguration.addAllowedHeader("*");UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**",corsConfiguration);return new CorsWebFilter(source);}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/319953.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Numpy数值计算

目录 1 ndarray创建方法 1.1 创建ndarray 1.2 ndarray常用属性&#xff1a; 1.3 代码测试如下&#xff1a; 1.4 其他函数创建ndarray 1.5 生成随机数的ndarray ​1.6 代码演示如下&#xff1a; 2 ndarray的基础操作 2.1 变换ndarray的形态 2.2 展平ndarray 2.3 组合…

IDEA JAVA Spring Boot运行Hello World(1.8)

参考资料&#xff1a; Spring Boot运行Hello World - 知乎https://blog.csdn.net/weixin_44005516/article/details/108293228(解决bug)SpringBoot入门第一章&#xff1a;Hello World-java教程-PHP中文网 (仅参考如何运行程序)java 8安装教程 java 8安装教程_java8安装-CSDN博…

我的2023

哈喽大家好&#xff0c;我是咸鱼。 果然出来工作后地球转速加快是正常现象&#xff0c;不知不觉 2023 年就结束了&#xff0c;我到现在都有种昨天刚过完 2023 年春节的恍惚。 工作时长已有一年多&#xff0c;刚开始接触工作的时候&#xff0c;有许多工作上的东西能够让我去学…

关于Python里xlwings库对Excel表格的操作(三十)

这篇小笔记主要记录如何【如何使用“Chart类”、“Api类"和“Axes函数”为新图表设置标题文本内容、字体、字号、粗细、正斜、颜色、坐标轴主要网格线】。前面的小笔记已整理成目录&#xff0c;可点链接去目录寻找所需更方便。 【目录部分内容如下】【点击此处可进入目录】…

各章练习题解析

目录 第1章 EDIT模型概述 题目 解析 第1章 EDIT模型概述 题目 第1题 第2题

cnPuTTY 0.80.0.1—PuTTY Release 0.80中文版本简单说明~~

2023-12-18 官方发布了PuTTY 0.80本次发布主要是针对Terrapin攻击(CVE-2023-48795)的修改发布。 更多详细的内容请查看PuTTY Change Log。 有关Terrapin攻击可用简单参考&#xff1a;警告&#xff01;&#xff01;&#xff01;Terrapin攻击(CVE-2023-48795)~~~ 为了缓解此漏洞…

Transformer从菜鸟到新手(二)

引言 这是Transformer的第二篇文章&#xff0c;上篇文章中我们了解了分词算法BPE&#xff0c;本文我们继续了解Transformer中的位置编码和核心模块——多头注意力。 位置编码 我们首先根据BPE算法得到文本切分后的子词标记&#xff0c;然后经过输入嵌入层将每个标记转换为对…

二级医院、专科医院his系统源码,java语言开发,系统运行稳定、功能齐全

二级医院、专科医院his系统源码&#xff0c;java语言开发 基于云计算技术的B/S架构的HIS系统&#xff0c;为医疗机构提供标准化的、信息化的、可共享的医疗信息管理系统&#xff0c;实现医患事务管理和临床诊疗管理等标准医疗管理信息系统的功能。 系统利用云计算平台的技术优…

[排序算法] 如何解决快速排序效率低的问题------三路划分

前言 在[C/C]排序算法 快速排序 (递归与非递归)一文中,对于快速排序的单趟排序一共讲了三种方法: hoare、挖坑法、双指针法 ,这三种方法实现的快速排序虽然在一般情况下效率很高,但是如果待排序数据存在大量重复数据,那这几种方法的效率就很低,而为了解决快速排序在这样特殊情况…

客服系统接入FastGPT

接入FastGPT 点击【应用】【外部使用】【API访问】【新建】新建一个KEY&#xff0c;同时也可以看到我们的API根地址 这个根地址和Key可以填入任何支持OpenAI接口的应用里&#xff0c;这个接口是兼容OpenAI格式。 在客服系统【知识库AI配置】里填上接口地址和接口密钥。这样我…

Shell:计算时间差 显示时分秒

1. 获取开始、结束时间&#xff08;获取当前时间&#xff09; start_timedate "%Y-%m-%d %H:%M:%S" end_timedate "%Y-%m-%d %H:%M:%S" 2. 计算时间差 durationecho $(($(date %s -d "${end_time}") - $(date %s -d "${start_time}"))…

Document对象详解

前言 在前端开发中&#xff0c;DOM&#xff08;文档对象模型&#xff09;扮演着重要的角色。它允许我们使用JavaScript来与网页文档进行交互&#xff0c;实现动态的网页效果。DOM的核心部分之一就是Document对象&#xff0c;它代表了整个HTML文档。在本篇博客中&#xff0c;我们…