深度剖析Gateway在微服务治理中的关键角色

目录

一、多层网关

二、Gateway 路由规则

        2.1 路由

        2.2 谓词

        2.3 过滤器

三、路由声明规则

        3.1 谓词

        寻址谓词

        请求参数谓词

        时间谓词

        自定义谓词


一、多层网关

        首先我们先了解下一个请求是如何到达服务端并得到相应的。过程如图所示:

        首先网址解析的第一步是 DNS 解析。当用户在浏览器输入网址后,这个网址会被 DNS 层解析成一个可被访问的 IP 地址。为了避免单点故障,可以在这一层加双保险,比如将域名映射成多个 IP 地址做主备,又或者根据用户 IP 所属区域做 Loadbanacer,将请求导向就近的 IP 地址。

        每一个 IP 地址只是所谓的虚 IP,后面会映射到一个大型的网关集群,这个集群便是我们业务系统外的第一道网关。在这个环节,使用最广泛而且最经济实惠技术选型就是 Nginx 反向代理。因为它拥有超强的并发能力,而且很节省内存资源。

        一个请求抵达最外层的 Nginx 服务之后,还可能会经历多级 LVS+Nginx 集群的转发。大公司之所以这么做,主要是出于对网络安全的考虑。他们往往会根据业务系统的属性和安全级别来设置不同的网络分区,而这些网络分区之间是相互独立的,分区之间需要开通白名单或者防火墙才能打通连接。比如有的网络分区可以直接对外,而有的高安全级别的分区(比如金融类业务)则部署在更底层。这就和我们使用跳板机访问线上机房是一个道理。

        然后,请求经过了多级网关服务的转发,抵达了最后的微服务层。在这一层上,Gateway 就需要出马来负责请求转发了。

        Gateway 既然叫“微服务网关”,就说明它自己就是一个微服务。换句话说,它也是 Nacos服务注册中心的一员。既然 Gateway 能连接到 Nacos,那么就意味着它可以轻松获取到 Nacos中所有服务的注册表。这样一来,Gateway 就可以根据本地的路由规则,将请求精准无误地送达到每个微服务组件中。

        使用 Gateway 有一个显而易见的好处,那就是高可扩展性。当你对后台的微服务集群做扩容或缩容的时候,Gateway 可以从 Nacos 注册中心轻松获取所有服务节点的变动,不需要任何额外的配置,一切都在无感知的情况下自然而然地发生。如果使用其他技术方案,你可能还需要花些力气修改节点列表,将新增的机器手动添加到列表中,还要把移除的机器从列表中删除。

二、Gateway 路由规则

        Gateway 的路由规则主要有三个部分,分别是路由、谓词和过滤器。如下图:

        

        2.1 路由

        路由是 Gateway 的一个基本单元,路由都有一个目标地址,这个目标地址就是当前路由规则要调用的目标服务。那么一条路由规则在什么情况下会调用目标服务呢?这就看路由的谓词设置了。

        2.2 谓词

        所谓谓词,实际上就是路由的判断规则,一个路由中可以添加多个谓词组合。如果一个服务请求满足某个路由里所有谓词规则,这时 Gateway 就会把请求转发到设置的目标地址。

        打个比方,你可以为某个路由设置一条谓词规则,约定访问路径的匹配规则为 Path=/user/*,在这种情况下只有以 /user 打头的请求才会被当前路由选中。

        Gateway 为我们提供了非常丰富的内置谓词,你可以通过内置谓词构建复杂的路由条件,甚至连“整点秒杀”这个场景都能在网关层做控制。

        2.3 过滤器

       过滤器和路由、目标地址之间是什么关系呢?其实 Gateway 在把请求转发给目标地址的过程中,把这个任务全权委托给了 Filter(过滤器)来处理。如下图:

        Gateway 组件使用了一种 FilterChain 的模式对请求进行处理,每一个服务请求(Request)在发送到目标服务之前都要被一串 FilterChain 处理。同理,在 Gateway 接收服务响应(Response)的过程中也会被 FilterChain 处理一把。

        Gateway 的过滤器主要分为两种,一种是 GlobalFilter,也就是“全局过滤器”;另一种是 GatewayFilter,也就是对指定路由生效的“局部过滤器”。

        Gateway 还有一系列用来做路径转发、请求跨域、WebSocket、WebClient 和 Loadbalancer 功能支持的全局过滤器。

三、路由声明规则

        路由是 Gateway 中的一条基本转发规则。网关在启动的时候,必须将这些路由规则加载到上下文中,才能正确处理服务转发请求。那么网关可以从哪些地方加载路由呢?

        Gateway 提供了三种方式来加载路由规则,分别是 Java 代码、ymal 文件和动态路由。

        第一种加载方式是 Java 代码声明路由,它是可读性和可维护性最好的方式,可以使用一种链式编程的 Builder 风格来构造一个 route 对象,比如在下面的例子里。它声明了两个路由,根据 path 的匹配规则将请求转发到不同的地址。

@Bean
public RouteLocator declare(RouteLocatorBuilder builder) {return builder.routes().route("id-001", route -> route.path("/user/**").uri("http://xxx.com")).route(route -> route.path("/test/**").uri("http://www.test.com")).build();
}

        第二种方式是通过配置文件来声明路由,你可以在 application.yml 文件中组装路由规则。我把前面定义的 Java 路由规则改写成了 yml 版,可以参考一下。

spring:cloud:gateway:httpclient:connect-timeout: 30000response-timeout: 30sroutes:- id: useruri: http://user.test.compredicates:- Path=/user/**filters:- name: HttpPostBodyEnhance- name: RequestRateLimiterargs:redis-rate-limiter.replenishRate: 1000redis-rate-limiter.burstCapacity: 1000redis-rate-limiter.requestedTokens: 1key-resolver: '#{@uriKeyResolver}'metadata:response-timeout: 20000connect-timeout: 20000- id: producturi: http://product.test.compredicates:- Path=/product/**metadata:response-timeout: 120000connect-timeout: 120000

        不管是 Java 版还是 yml 版,它们都是通过“hardcode”的方式声明的静态路由规则,这些 Route 只会在项目启动后被加载一次。如果你想要在 Gateway 运行期更改路由逻辑,那么就要使用第三种方式:动态路由加载。

        动态路由也有不同的实现方式。如果你在项目中集成了 actuator 服务,那么就可以通过 Gateway 对外开放的 actuator 端点在运行期对路由规则做增删改查。但这种修改只是临时性的,项目重新启动后就会被打回原形,因为这些动态规则并没有持久化到任何地方。

        动态路由还有另一种实现方式,那就是借助 Nacos 配置中心来存储路由规则。Gateway 通过监听 Nacos Config 中的文件变动,就可以动态获取 Nacos 中配置的规则,并在本地生效了。我将在后面的课程中带你落地一套 Nacos+Gateway 的动态路由。

        3.1 谓词

        Gateway 的内置谓词很多,这里捡一些比较常用的谓词,为你介绍下它们的用法。我把这些谓词大致分为三个类型:寻址谓词、请求参数谓词和时间谓词。我将使用基于 Java 代码的声明方式,带你挨个来看下如何在路由中配置谓词。

        寻址谓词

        针对请求地址和类型做请求判断的谓词条件,比如这里用到的 path,其实就是一种路径匹配条件,当请求的 URL 和 path 谓词指定的模式相匹配时,这个谓词就会返回一个 TRUE 的判断,而 method 谓词则是根据请求的 http method 作为判断条件,比如这里就限定了只有 GET 和 POST 请求才能访问当前 Route。

.route("id-1", route -> route.path("/user/**").and().method(HttpMethod.GET, HttpMethod.POST).uri("http://user.test.com")

        在上面这段代码中,添加了不只一个谓词。在谓词与谓词之间,可以使用and、or、negate这类与或非逻辑连词进行组合,构造一个复杂判断条件。

        请求参数谓词

        这类谓词主要对请求所附带的参数进行判断。这里的参数不单单是 Query 参数,还可以是Cookie 和 Header 中包含的参数。如下代码,如果请求中包含指定参数,或者指定参数的值和指定的 regex 表达式不匹配,那么请求就无法满足当前路由的谓词判断。

.route("id-1", route -> route// 验证cookie.cookie("myCookie", "regex")// 验证header.and().header("myHeaderA").and().header("myHeaderB", "regex")// 验证param.and().query("paramA").and().query("paramB", "regex").and().remoteAddr("远程服务地址").and().host("pattern1", "pattern2")

        时间谓词

        可以借助before、after、between这三个时间谓词来控制当前路由的生效时间段。

.route("id-1", route -> route// 在指定时间之前.before(ZonedDateTime.parse("2024-04-25T14:33:47.789+08:00"))// 在指定时间之后.or().after(ZonedDateTime.parse("2024-04-25T14:33:47.789+08:00"))// 或者在某个时间段以内.or().between(ZonedDateTime.parse("起始时间"),ZonedDateTime.parse("结束时间"))

        自定义谓词

        如果内置谓词不满足要求,想要实现自定义谓词,可以通过 Gateway 的可扩展谓词工厂来实现自定义谓词,Gateway 组件提供了一个统一的抽象类 AbstractRoutePredicateFactory 作为谓词工厂,你可以通过继承这个类来添加新的谓词逻辑。

        

// 继承自通用扩展抽象类AbstractRoutePredicateFactory
public class MyPredicateFactory extends AbstractRoutePredicateFactory<MyPredicateFactory.Config> {public MyPredicateFactory() {super(Config.class);}// 定义当前谓词所需要用到的参数@Validatedpublic static class Config {private String myField;}@Overridepublic List<String> shortcutFieldOrder() {// 声明当前谓词参数的传入顺序// 参数名要和Config中的参数名称一致return Arrays.asList("myField");}// 实现谓词判断的核心方法// Gateway会将外部传入的参数封装为Config对象@Overridepublic Predicate<ServerWebExchange> apply(Config config) {return new GatewayPredicate() {// 在这个方法里编写自定义谓词逻辑@Overridepublic boolean test(ServerWebExchange exchange) {return true;}@Overridepublic String toString() {return String.format("myField: %s", config.myField);}};}
}

        

往期经典推荐

手把手教你实现服务高可用性-CSDN博客

决胜微服务架构:OpenFeign轻量级REST客户端的魅力解析_feign配置loadbalancer-CSDN博客

一文看懂Nacos如何实现高效、动态的配置中心管理_nacos 动态配置-CSDN博客

TiDB内核解密:揭秘其底层KV存储引擎如何玩转键值对_tidb 的key value是如何做到的-CSDN博客

深入剖析MongoDB集群架构设计_mongodb 集群-CSDN博客

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

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

相关文章

设计模式学习笔记 - 开源实战四(中):剖析Spring框架中用来支持扩展的设计模式

概述 上篇文章&#xff0c;学习了 Spring 框架背后蕴含的设计思想&#xff0c;比如约定优于配置、低侵入松耦合、模块化轻量级等等。这些设计思想可以借鉴到其他框架开发中&#xff0c;在大的设计层面提高框架的代码质量。 除了上篇文章降到的设计思想&#xff0c;实际上&…

CSS特效---环形进度条

1、演示 2、一切尽在代码中 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name"viewport" content"w…

炉管设备的内部构造详解

知识星球&#xff08;星球名&#xff1a;芯片制造与封测社区&#xff09;里的学员问&#xff1a;炉管设备&#xff08;立式&#xff09;的内部构造是怎样的&#xff1f; 如上图&#xff0c;是一个典型的&#xff1a; 上半部&#xff1a; Heating Element&#xff08;加热线圈…

树莓派使用总结

手上拿到了一块Raspberry Pi 4B板子。研究一下怎么用。 安装系统 直接到官网【Raspberry Pi 】下载在线安装助手 安装好后&#xff0c;打开软件&#xff0c;选择好板子型号、系统、TF卡&#xff0c;一路下一步就行。 树莓派接口 直接查看官方的资料【Raspberry Pi hardwar…

实用电路图轻松掌握,一通百通 | 百能云芯

通过以下各种各样的实用电路&#xff0c;大家可以了解元器件的结构、特性、动作原理及电路的基本控制方式&#xff0c;掌握一些控制规律&#xff0c;这样的话&#xff0c;在日后的电路识图中就能融会贯通&#xff0c;一通百通。 文章中的电路图有难有易&#xff0c;有些图现在…

贪吃蛇项目实战——学习详解

前言:贪吃蛇是一个经典的游戏&#xff0c; 本节将使用c语言实现一个简易的的贪吃蛇小游戏。 本节内容适合已经学完c语言还有数据结构链表的友友们。 我们要实现的贪吃蛇是在控制台进行游戏的。 它运行起来是这样的&#xff1a; 贪吃蛇 那么&#xff0c; 为了实现这个小游戏。 我…

YOLO8实战:行人跌倒检测系统

yolo8行人跌倒检测系统 前言 随着科技的不断进步&#xff0c;人工智能和深度学习技术已广泛应用于各行各业&#xff0c;尤其是在人身安全检测方面。传统的跌倒检测方法依赖于人工观察&#xff0c;但这种方法不仅耗时耗力&#xff0c;而且容易因人为因素导致误判或漏判。因此&a…

叉车4G无线视频监控管理解决方案:提升效率,保障安全

在现代物流行业中&#xff0c;叉车被广泛应用于仓储和物流领域&#xff0c;成为提升效率和降低成本的重要工具。然而&#xff0c;叉车作为重要的运输设备&#xff0c;其安全性和管理效率也备受关注。针对这一问题&#xff0c;叉车4G无线视频监控管理解决方案应运而生。 叉车是仓…

C++从零开始websevere服务器从搭建到上线|使用华为云服务器进行项目部署

文章目录 公网IP和私有IP地址公网IP私有IP地址为什么我们需要两个IP地址呢 云服务器设置防火墙配置基础配置云服务器防火墙配置云服务器安全组 总结 问题背景 关于使用华为云服务器进行项目部署&#xff0c;25届C秋招选手&#xff0c;刚写完一个websever项目&#xff0c;想着部…

工厂方法模式设计实验

【实验内容】 楚锋软件公司欲开发一个系统运行日志记录器&#xff08;Logger&#xff09;。该记录器可以通过多种途径保存系统的运行日志&#xff1a;例如通过文件记录或数据库记录&#xff0c;用户可以通过修改配置文件灵活地更换日志记录方式。在设计各类日志记录器时&#…

【智能算法】回溯搜索算法(BSA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2013年&#xff0c;P Civicioglu等人受到当前种群与历史种群之间的差分向量的引导启发&#xff0c;提出了回溯搜索算法&#xff08;Backtracking Search Algorithm, BSA&#xff09;。 2.算法原理…

刷题训练之二分查找

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;熟练掌握二分查找算法 > 毒鸡汤&#xff1a;学习&#xff0c;学习&#xff0c;再学习 ! 学&#xff0c;然后知不足。 > 专栏选自&#xff1a;刷题…

分析 MyBatis/MyBatis-Plus 慢 SQL 的分析组件 --SQL 慢镜️‍♀️

大家好&#xff01;我是聪ζ&#x1f331;我做了一个分析 MyBatis/MyBatis-Plus 慢 SQL 的分析组件 --SQL 慢镜&#x1f575;️‍♀️ GitHub仓库地址&#x1f680;: https://github.com/lhccong/sql-slow-mirror 点点 star 我的朋友们✨ 背景&#x1f9ca;&#xff1a; 大家…

(十五)C++自制植物大战僵尸游戏僵尸基类讲解

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/m0EtD 在游戏中,最重要的两个类别就是植物与僵尸。僵尸可以对植物进行攻击,不同的僵尸攻击方式可能会不同,但是不同又有许多相同的属性。在基类(父类)中定义僵尸共有属性,供派生类(子类)继承。 僵尸状态转换 僵尸…

Nacos分布式配置中心

<?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 https://…

Android永不息屏和关闭锁屏

作者简介&#xff1a; 一个平凡而乐于分享的小比特&#xff0c;中南民族大学通信工程专业研究生在读&#xff0c;研究方向无线联邦学习 擅长领域&#xff1a;驱动开发&#xff0c;嵌入式软件开发&#xff0c;BSP开发 作者主页&#xff1a;一个平凡而乐于分享的小比特的个人主页…

kali——勒索病毒metasploit

我先来叙述一下大致流程&#xff1a; 1、使用mfs对 445端口进行攻击获得一系列权限 2、更新mfs版本 3、使用search 17_010对命令进行查看 4、use auxiliary/scanner/smb/smb_ms17_010使用该模块设置靶机set rhosts 靶机ip和设置本机监听端口 set lhost 0-65535 5、options…

数智亚运,为什么需要智能电子桌牌?

近日&#xff0c;杭州亚运会博物馆正式对公众开放&#xff0c;深度还原了杭州从申请办、筹办至举办亚运会的各个精彩历程。馆内有“亚运与杭州”、“亚运与亚洲”“亚运与未来”三大板块展示区&#xff0c;展示了大量亚运会使用过的实物&#xff0c;还有当时引人注目的数字科技…

53、图论-课程表

思路&#xff1a; 其实就是图的拓扑排序&#xff0c;我们可以构建一个图形结构&#xff0c;比如[0,1]表示1->0&#xff0c;对于0来说入度为1。 遍历结束后&#xff0c;从入度为0的开始遍历。引文只有入度为0的节点没有先决条件。然后依次减少1。直到所有节点入度都为0.然后…

开发同城O2O跑腿系统源码:构建高效便捷的本地服务平台教程

为了满足用户对便捷的需求&#xff0c;今天我们将一同探讨如何开发一个高效便捷的同城O2O跑腿系统&#xff0c;以构建一个功能全面、操作简单的本地服务平台。 一、确定需求和功能 在开发同城O2O跑腿系统之前&#xff0c;首先需要明确系统的需求和功能。用户可以通过该系统发布…