【微服务-网关】SpringCloud GateWay核心技术

在前面的文章中我们介绍了微服务网关的基础知识,了解了什么是网关,网关有什么作用,以及市面上有哪些成熟的网关产品,最后了解了网关的配置技巧。通过上篇文章,大家应该可以在微服务架构中完成网关的基本配置。 但是,文末最后也说了,自动路由可以解决简单的转发规则,但对于企业中遇到的复杂、特殊的路由转发规则,就不是自动路由能解决的了。SpringCloud GateWay项目中内置了强大的“谓词”系统,可以满足企业应用中的各种转发规则要求,下面我们就一起来看看吧!

一、谓词(Predicate)

在介绍前,我们先要了解一下网关的三个关键名词:路由(Route)、谓词(Predicate)、过滤器(Filter)。

路由(Route)是指一个完整的网关地址映射与处理过程。一个完整的路由包含两部分配置:谓词(Predicate)与过滤器(Filter)。前端应用发来的请求要被转发到哪个微服务上,是由谓词决定的;而转发过程中请求、响应数据被网关如何加工处理是由过滤器决定的。

我们通过实例来介绍,将上篇文章中的工程复制过来,修改一下application.yml文件:

spring:

  application:

    name: gateway

  cloud:

    nacos:

      discovery:

        server-addr: 106.14.221.171:8848

        username: nacos

        password: nacos

    gateway: 

      discovery:

        locator:

          enabled: false #不再需要Gateway路由转发

      routes:  #路由规则配置

        #第一个路由配置,service-a路由规则

        - id: service_a_route #路由唯一标识

          #lb开头代表基于gateway的负载均衡策略选择实例

          uri: lb://service-a 

          #谓词配置

          predicates:

            #Path路径谓词,代表用户端URI如果以/a开头便会转发到service-a实例

            - Path=/a/** 

            #After生效时间谓词,2024年5月1日后该路由才能在网关对外暴露

            - After=2024-15-01T00:00:00.000+08:00[Asia/Shanghai]

          #谓词配置

          filters:

            #忽略掉第一层前缀进行转发

          - StripPrefix=1 

            #为响应头附加X-Response=Blue

          - AddResponseHeader=X-Response,Blue 

        #第二个路由配置,service-b路由规则

        - id: service_b_route

          uri: lb://service-b

          predicates:

            - Path=/b/**

          filters:

            - StripPrefix=1

server:

  port: 80

management:

  endpoints:

    web:

      exposure:

        include: '*'

配置释义:在 2024 年 5 月 1 日后,当用户端发来/a/...开头的请求时,Spring Cloud Gateway 会自动获取 service-a 可用实例,默认采用轮询方式将URI附加至实例地址后,形成新地址,service-a处理后 Gateway 网关自动在响应头附加 X-Response=Blue。至于第二个 service_b_route,比较简单,只说明当用户访问/b开头 URL 时,转发到 service-b 可用实例。

这里提供一个完整的路由配置固定格式:

spring:

    gateway: 

      discovery:

        locator:

          enabled: false  #不再需要Gateway路由转发

      routes: 

        - id: xxx #路由规则id

          uri: lb://微服务id  #路由转发至哪个微服务

          predicates: 

         //具体的谓词

         filters:

         //具体的过滤器

其中 predicates 是重点,说明路由生效条件,这里我们将常见的谓词使用形式举例出来:

1、After

After代表在指定时间点后路由规则生效

predicates:

    - After=2024-05-01T00:00:00.000+08:00

2、Before

Before代表在指定时间点前路由规则生效

predicates:

    - Before=2024-05-01T17:42:47.789-07:00[America/Denver]

3、Path

Path 代表 URI 符合映射规则时生效

predicates:

    - Path=/b/**

4、Header

Header 代表包含指定请求头时生效

predicates:

    - Header=X-Request-Id, \d+

5、Method

Method 代表要求 HTTP 方法符合规定时生效

predicates:

    - Method=GET

谓词是 Gateway 网关中最灵活的部分,上面列举的是最常用的谓词,还有很多谓词是在文中没有提到,有兴趣可以到官网中学习。

二、过滤器(Filter)

过滤器(Filter)可以对请求或响应的数据进行额外处理,下面我们也来列举几个常用的过滤器

1、AddRequestParameter

AddRequestParameter 是对所有匹配的请求添加一个查询参数

filters:

- AddRequestParameter=id,2 #在请求参数中追加id=2

2、AddResponseHeader

AddResponseHeader 会对所有匹配的请求,在返回结果给客户端之前,在 Header 中添加响应的数据

#在Response中添加Header头,key=token,Value=123。

filters:

- AddResponseHeader=token,123

3、Retry

Retry 为重试过滤器,当后端服务不可用时,网关会根据配置参数来发起重试请求

filters:

#涉及过滤器参数时,采用name-args的完整写法

- name: Retry #name是内置的过滤器名

  args: #参数部分使用args说明

    retries: 3

    status: 503
# 含义为,当后端服务返回 503 状态码的响应后,Retry 过滤器会重新发起请求,最多重试 3 次

三、GateWay的执行原理

在了解了SpringCloud GateWay配置和谓词用法后,我们再来看一下GateWay的底层实现。

执行流程图如下:

  • 1、Spring Cloud Gateway 启动时基于 Netty Server 监听指定的端口(该端口可以通过 server.port 属性自定义)。当前端应用发送一个请求到网关时,进入 Gateway Handler Mapping 处理过程,网关会根据当前 Gateway 所配置的谓词(Predicate)来决定是由哪个微服务进行处理。

  • 2、确定微服务后,请求向后进入 Gateway Web Handler 处理过程,该过程中 Gateway 根据过滤器(Filters)配置,将请求按前后顺序依次交给 Filter 过滤链进行前置(Pre)处理,前置处理通常是对请求进行前置检查,例如:判断是否包含某个指定请求头、检查请求的 IP 来源是否合法、请求包含的参数是否正确等。

  • 3、当过滤链前置(Pre)处理完毕后,请求会被 Gateway 转发到真正的微服务实例进行处理,微服务处理后会返回响应数据,这些响应数据会按原路径返回被 Gateway 配置的过滤链进行后置处理(Post),后置处理通常是对响应进行额外处理,例如:将处理过程写入日志、为响应附加额外的响应头或者流量监控等。

可以看到,在整个处理过程中谓词(Predicate)与过滤器(Filter)起到了重要作用,谓词决定了路径的匹配规则,让 Gateway 确定应用哪个微服务,而 Filter 则是对请求或响应作出实质的前置、后置处理。

在项目中功能场景多种多样,像日常的用户身份鉴权、日志记录、黑白名单、反爬虫等基础功能都可以通过自定义 Filter 为 Gateway 进行功能扩展。

四、自定义全局过滤器实战

在 Spring Cloud Gateway 中,自定义过滤器分为两种:全局过滤器局部过滤器。两者唯一的区别是:全局过滤器默认应用在所有路由(Route)上,而局部过滤器可以为指定的路由绑定。下面通过“计时过滤器”这个案例介绍全局过滤器的配置。所谓计时过滤器是指任何从网关访问的请求,都要在日志中记录下从请求进入到响应退出的执行时间,通过这个时间运维人员便可以收集并分析哪些功能进行了慢处理,以此为依据进行进一步优化。下面是计时过滤器的代码:

package com.example.gateway.filter;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;

import org.springframework.cloud.gateway.filter.GlobalFilter;

import org.springframework.core.Ordered;

import org.springframework.stereotype.Component;

import org.springframework.web.server.ServerWebExchange;

import reactor.core.publisher.Mono;

@Component //自动实例化并被Spring IOC容器管理

//全局过滤器必须实现两个接口:GlobalFilter、Ordered

//GlobalFilter是全局过滤器接口,实现类要实现filter()方法进行功能扩展

//Ordered接口用于排序,通过实现getOrder()方法返回整数代表执行当前过滤器的前后顺序

public class ElapsedFilter implements GlobalFilterOrdered {

    //基于slf4j.Logger实现日志输出

    private static final Logger logger = LoggerFactory.getLogger(ElapsedFilter.class);

    //起始时间属性名

    private static final String ELAPSED_TIME_BEGIN = "elapsedTimeBegin";

    /**

     * 实现filter()方法记录处理时间

     * @param exchange 用于获取与当前请求、响应相关的数据,以及设置过滤器间传递的上下文数据

     * @param chain Gateway过滤器链对象

     * @return Mono对应一个异步任务,因为Gateway是基于Netty Server异步处理的,Mono对就代表异步处理完毕的情况。

     */


    @Override

    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        //Pre前置处理部分

        //在请求到达时,往ServerWebExchange上下文环境中放入了一个属性elapsedTimeBegin,保存请求执行前的时间戳

        exchange.getAttributes().put(ELAPSED_TIME_BEGIN, System.currentTimeMillis());



        //chain.filter(exchange).then()对应Post后置处理部分

        //当响应产生后,记录结束与elapsedTimeBegin起始时间比对,获取RESTful API的实际执行时间

        return chain.filter(exchange).then(

                Mono.fromRunnable(() -> { //当前过滤器得到响应时,计算并打印时间

                    Long startTime = exchange.getAttribute(ELAPSED_TIME_BEGIN);

                    if (startTime != null) {

                        logger.info(exchange.getRequest().getRemoteAddress() //远程访问的用户地址

                                + " | " +  exchange.getRequest().getPath()  //Gateway URI

                                + " | cost " + (System.currentTimeMillis() - startTime) + "ms"); //处理时间

                    }

                })

        );

    }

    //设置为最高优先级,最先执行ElapsedFilter过滤器

    //return Ordered.LOWEST_PRECEDENCE; 代表设置为最低优先级

    @Override

    public int getOrder() {

        return Ordered.HIGHEST_PRECEDENCE;

    }

}

运行后通过 Gateway 访问任意微服务便会输出日志:

2024-03-1 12:36:01.765  INFO 14052 --- [ctor-http-nio-4] com.example.gateway.filter.ElapsedFilter   : /0:0:0:0:0:0:0:1:57873 | /test-service/test | cost 821ms

以上就是全局过滤器的开发方法,至于局部过滤器的配置方法与全局过滤器极为相似,有兴趣可以通过官方文档了解更详细的内容。

下一篇开始,我们来介绍一下微服务环境下如何通过服务降级、熔断等机制来保护我们的微服务架构,避免雪崩效应的发生。感兴趣的小伙伴可以持续关注。

文章将持续更新,欢迎关注公众号:服务端技术精选。欢迎点赞、关注、转发

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

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

相关文章

2022 年甘肃省职业院校技能大赛 高职组 网络系统管理竞赛 网络构建模块试题

2022 年甘肃省职业院校技能大赛 高职组网络系统管理竞赛 网络构建模块试题 目 录 考试说明… 3 任务描述… 3 任务清单… 3 &#xff08;一&#xff09;基础配置… 3 &#xff08;二&#xff09;有线网络配置… 4 &#xff08;三&#xff09;无线网络配置… 6 &#xff08;四&a…

老大语录六 谈产品规划

老大语录六 谈产品规划 产品经理一个重要的职责就是做产品规划。它是考验产品经理对市场和需求的阅读能力,是决定一个产品在市场上跟竞争对手分出高下的必要条件,是最能体现产品经理水平的工作。 然而我们往往在执行过程中在这一步上做的并不是特别好。虽然很多企业都会容易建…

2024 年 5 款适用于 Linux 的参考文献管理软件

时间是宝贵的&#xff0c;因此如果某款软件能让您摆脱必须执行的日常繁琐任务&#xff0c;那么它就会派上用场。 参考文献管理工具就是此类软件的典型代表&#xff0c;只需点击几下就能自动格式化引文。学生、教育工作者、作家、科学家和研究人员一定会发现它们非常有用。 在…

NFTScan | 03.18~03.24 NFT 市场热点汇总

欢迎来到由 NFT 基础设施 NFTScan 出品的 NFT 生态热点事件每周汇总。 周期&#xff1a;2024.03.18~ 2024.03.24 NFT Hot News 01/ NFT 系列 NodeMonkes 地板价已超越 BAYC 3 月 18 日&#xff0c;据数据显示&#xff0c;NFT 系列 NodeMonkes 地板价已超越 Bored Ape Yacht …

9.2024

使用冒泡排序给{10 ,1,35,61,89,36,55}排序 代码&#xff1a; public class 第九题 {public static void main(String[] args) {int a[]{10,1,35,61,89,36,55};for (int i0;i<a.length-1;i){for (int j0;j<a.length-1;j){if (a[j]>a[j1]){int temp0;tempa[j];a[j]a[…

光致发光荧光量子产率测试光纤光谱仪

光致发光荧光量子产率测试系统是一种用于测量材料发光效率的高精度设备&#xff0c;它通过光致发光方法来确定样品的发射效率。光致发光荧光量子产率测试系统不仅提供了一种高效、可靠的测量手段&#xff0c;而且对于提升科学研究和工业应用中的发光材料性能具有重要作用。通过…

nacos集群搭建实战

集群结构图 初始化数据库 Nacos默认数据存储在内嵌数据库Derby中&#xff0c;不属于生产可用的数据库。官方推荐的使用mysql数据库&#xff0c;推荐使用数据库集群或者高可用数据库。 首先新建一个数据库&#xff0c;命名为nacos&#xff0c;而后导入下面的SQL&#xff08;直…

日常刷题之77-组合

题目 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案 提示&#xff1a;假设 n5,k3 就是需要组合出来&#xff0c;长度3且内容数据是在[1,n]这个区间内的所有可能得组合 同时一个组合里面内个数字只能出现一次&#…

日增500粉的全自动引流神器

全自动引流&#xff0c;采集曝光一体每天截流500&#xff0c;这是每个企业主和网红的终极梦想。今日&#xff0c;我将分享一套高效而可行的引流策略&#xff0c;帮助你实现这个目标。 我们需要理解&#xff0c;全自动引流并不意味着无人参与。相反&#xff0c;它仍需要你的参与…

【王道训练营】第6题 输入一个整型数,判断是否是对称数,如果是,输出yes,否则输出no

文章目录 我的代码改正代码其他代码 我的代码 没有完成 #include<stdio.h> int main(){int a;int b;int c0;//位数int d0;//比较几次scanf("%d",&a);while(b!0){bb/10;c;}dc/2;//比较几次int ffor(int i0 ;i<d;i){int ec;//位数fa - a / (((e-i-1)*10…

算法笔记~—位运算

目录 常见位运算&#xff1a; 1、基础位运算 2、对于一个数n。确定、修改这个数n二进制x位。 3、提取&#xff08;确定&#xff09;一个数n最右侧的1&#xff08;bit&#xff09;与干掉最右侧的1&#xff08;bit&#xff09; 4、异或运算律 5、位运算的优先级&#xff1a…

Go --- Go语言垃圾处理

概念 垃圾回收&#xff08;GC-Garbage Collection&#xff09;暂停程序业务逻辑SWT&#xff08;stop the world&#xff09;程序根节点&#xff1a;程序中被直接或间接引用的对象集合&#xff0c;能通过他们找出所有可以被访问到的对象&#xff0c;所以Go程序的根节点通常包括…

虚拟机Linux-openEuler硬盘空间扩容

虚拟机Linux-openEuler硬盘空间扩容 1、需求场景 我们在使用虚拟机时&#xff0c;可能会出现磁盘空间不够用导致各种bug出现的情况。 首先&#xff0c;我们要扩展虚拟机的可用磁盘空间。如图所示&#xff0c;我的原本硬盘大小为8G&#xff0c;我们扩展到30GB 2、打开虚拟机…

【git分支管理策略】如何高效的管理好代码版本

目录 1.分支管理策略 2.我用的分支管理策略 3.一些常见问题 1.分支管理策略 分支管理策略就是一些经过实践后总结出来的可靠的分支管理的办法&#xff0c;让分支之间能科学合理、高效的进行协作&#xff0c;帮助我们在整个开发流程中合理的管理好代码版本。 目前有两套Git…

【GameFramework框架内置模块】16、配置(Setting)

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址QQ群&#xff1a;398291828 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 【GameFramework框架】系列教程目录&#xff1a;…

2024年软件测试,“我“从初级到高级进阶,不再走弯路...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 现在2024年&#…

54、Qt/对话框、事件机制相关学习20240325

一、完善对话框&#xff0c;点击登录按钮&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后&#xff0c;关闭登录界面&#xff0c;跳转到其他界面 如果账号和密码不匹配&#…

python(django)之单一接口管理功能后台开发

1、创建数据模型 在apitest/models.py下加入以下代码 class Apis(models.Model):Product models.ForeignKey(product.Product, on_deletemodels.CASCADE, nullTrue)# 关联产品IDapiname models.CharField(接口名称, max_length100)apiurl models.CharField(接口地址, max_…

服务运营|香港大学雷骁:收益管理中价格歧视的公平性

编者按&#xff1a; INFORMS George B. Dantzig Dissertation Award 用于表彰运筹学和管理科学领域中具有创新性和实用性的最佳毕业设计。香港大学助理教授雷骁题为“Revenue Management in Video Games and With Fairness” 是这一奖项2023年度的提名者之一。 这篇毕业设计重…

PMSM 永磁同步电机滑膜控制 SVPWM矢量控制 matlab simulink 仿真

仿真搭建平台&#xff1a; (1)该模型采用matlab/simulink 2016b版本搭建&#xff0c;使用matlab 2016b及以上版本打开最佳; (2)该模型已经提前转换了各个常用版本&#xff08;最低为matlab2012b&#xff09;&#xff0c;防止出现提示版本过高的情况。 模型截图&#xff1a; 算…