系列十、Spring Cloud Gateway

news2024/11/26 18:32:42

一、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
    @Validated
    public 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(){
            @Override
            public 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
    @NoArgsConstructor
    public 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 {

    @Bean
    public 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.coloradmin.cn/o/1357475.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

优雅实现微信小程序动态tabBar,根据不同用户角色显示不同底部导航——更新版(支持自由组合总数超过5个tabBar菜单)

背景 在开发小程序过程中&#xff0c;有个需求是&#xff0c;小程序底部的tabBar需要根据不同用户角色显示不同底部导航。此时就需要用到自定义底部导航 custom-tab-bar。 上次发文是组合显示4个底部tabBar导航&#xff0c;很多小伙伴评论说组合超过5个怎么办。他们的需求总数…

Android中的Intent

一.显式Intent 显示Intent是明确目标Activity的类名 1. 通过Intent(Context packageContext, Class<?> cls)构造方法 2.通过Intent的setComponent()方法 3.通过Intent的setClass/setClassName方法 通过Intent(Context packageContext, Class<?> cls)构造方法 通…

JVM之对象创建

对象创建的流程 1.类加载检查 虚拟机遇到一条new指令时&#xff0c;首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用&#xff0c;并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有&#xff0c;那必须先执行相应的类加载过程。new指令对…

Callback Hook

一、Callback Hook 函数名&#xff1a;useCallback 用于得到一个固定引用值的函数&#xff0c;通常用它进行性能优化。 useCallback: 该函数只需要传入两个参数&#xff1a;一个回调函数和一个依赖数组即可。 1.函数&#xff0c;useCallback会固定该函数的引用&#xff0c;…

【Rust日报】Piccolo - 用纯Rust实现的无栈Lua虚拟机

Piccolo - 用纯Rust实现的无栈Lua虚拟机 Piccolo&#xff0c;原名luster&#xff0c;在经过数年的中断后&#xff0c;于2023年4月悄然恢复了开发。曾经开发过 rlua 的 kyren&#xff0c;在底层 gc-arena crate 取得突破后&#xff0c;回到了 piccolo 项目。这两个项目现在已经&…

Python:界面开发,wx入门篇

以下内容为本人的学习笔记&#xff0c;如需要转载&#xff0c;请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/3Yb_YAKiMte_f5HanetXiA 本文大概 3617 个字&#xff0c;阅读需花 10 分钟 内容不多&#xff0c;但也花了一些精力 如要交流&#xff0c;欢迎评…

极速 JavaScript 打包器:esbuild

文章目录 引言什么是esbuild&#xff1f;esbuild的特点esbuild如何实现如此出色的性能&#xff1f;esbuild缺点基本配置入口文件输出文件模块格式targetplatformexternalbanner和footer 高级配置插件系统自定义插件压缩代码调试代码 结论&#x1f636; 写在结尾 引言 esbuild是…

leetcode:724. 寻找数组的中心下标

一、题目 二、函数原型 int pivotIndex(int* nums, int numsSize) 三、思路 首先要理解正确中心下标&#xff0c;中心下标左侧元素之和等于右侧元素之和&#xff0c;比较时是不包含中心下标所指元素的。 先将数组和求出来记为sum&#xff0c;再遍历数组&#xff0c;遍历到…

快速批量运行命令

Ansible 是 redhat 提供的自动化运维工具&#xff0c;它是 Python编写&#xff0c;可以通过 pip 安装。 pip install ansible 它通过任务(task)、角色(role)、剧本(playbook) 组织工作项目&#xff0c;适用于批量化系统配置、软件部署等需要复杂操作的工作。 但对于批量运行命…

pytorch集智-1安装与简单使用

1 安装 1.1 简介 pytorch可用gpu加速&#xff0c;也可以不加速。gpu加速是通过cuda来实现&#xff0c;cuda是nvidia推出的一款运算平台&#xff0c;它可以利用gpu提升运算性能。 所以如果要装带加速的pytorch&#xff0c;需要先装cuda&#xff0c;再装pytorch&#xff0c;如…

【重点】【BFS】542.01矩阵

题目 法1&#xff1a;经典BFS 下图中就展示了我们方法&#xff1a; class Solution {public int[][] updateMatrix(int[][] mat) {int m mat.length, n mat[0].length;int[][] dist new int[m][n];boolean[][] used new boolean[m][n];Queue<int[]> queue new Li…

excel中解决多行文本自动调整行高后打印预览还是显示不全情况

注意&#xff1a;此方法对于多行合并后单元格行高调整不适用&#xff0c;需要手动调整&#xff0c;如大家有简便方法&#xff0c;欢迎评论。 一、调整表格为自动调整行高 1&#xff09;点击此处全选表格 2&#xff09;在第一行序号单元格的下端&#xff0c;鼠标成黑十字时&am…

【React系列】父子组件通信—props属性传值

本文来自#React系列教程&#xff1a;https://mp.weixin.qq.com/mp/appmsgalbum?__bizMzg5MDAzNzkwNA&actiongetalbum&album_id1566025152667107329) 一. 认识组件的嵌套 组件之间存在嵌套关系&#xff1a; 在之前的案例中&#xff0c;我们只是创建了一个组件App&…

机器人制作开源方案 | 清洁机器人

作者&#xff1a;胡志宇、白永康、颉志国、刘昭迅、王维浩 单位&#xff1a;北京石油化工学院 指导老师&#xff1a;陈亚、王殿军 1. 设计方案论证 1.1 清洁机器人方案选择 目前&#xff0c;市场上清洁机器人比比皆是&#xff0c;各大品牌之间的竞争也相当激烈&#xff0c;…

docker kafka go demo

配置 创建网桥 docker network create app-tier --driver bridge拉取并启动镜像 docker run -d --name kafka-server --hostname kafka-server \--network app-tier \-p 9092:9092 \-e ALLOW_PLAINTEXT_LISTENERyes \-e KAFKA_CFG_ADVERTISED_LISTENERSPLAINTEXT://192.168.…

链表--206. 反转链表/easy

206. 反转链表 1、题目2、题目分析3、解题步骤4、复杂度最优解代码示例5、抽象与扩展 1、题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2…

【大数据进阶第二阶段之Hadoop学习笔记】Hadoop 运行环境搭建

【大数据进阶第二阶段之Hadoop学习笔记】Hadoop 概述-CSDN博客 【大数据进阶第二阶段之Hadoop学习笔记】Hadoop 运行环境搭建-CSDN博客 【大数据进阶第二阶段之Hadoop学习笔记】Hadoop 运行模式-CSDN博客 1、模板虚拟机环境准备 1.1、 hadoop100 虚拟机配置要求如下 &…

如何通过Python将各种数据写入到Excel工作表

在数据处理和报告生成等工作中&#xff0c;Excel表格是一种常见且广泛使用的工具。然而&#xff0c;手动将大量数据输入到Excel表格中既费时又容易出错。为了提高效率并减少错误&#xff0c;使用Python编程语言来自动化数据写入Excel表格是一个明智的选择。Python作为一种简单易…

【Spring进阶系列丨第六篇】Spring的Bean管理(基于注解)

文章目录 一、说明二、用于创建对象的2.1、Component注解2.1.1、定义Bean2.1.2、主配置文件配置扫描注解2.1.3、测试2.1.4、Component注解总结 2.2、Controller注解2.3、Service注解2.4、Repository注解 三、用于注入数据的3.1、Autowired注解3.1.1、定义Bean3.1.2、主配置文件…

《PCI Express体系结构导读》随记 —— 第I篇 第2章 PCI总线的桥与配置(6)

接前一篇文章&#xff1a;《PCI Express体系结构导读》随记 —— 第I篇 第2章 PCI总线的桥与配置&#xff08;5&#xff09; 2.2 HOST主桥 本节以MPC8548处理器为例&#xff0c;说明HOST主桥在PowerPC处理器中的实现机制&#xff0c;并简要介绍x86处理器系统使用的HOST主桥。 …