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

news2024/11/25 6:43:33

目录

一、多层网关

二、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: 30000
        response-timeout: 30s
      routes:
      - id: user
        uri: http://user.test.com
        predicates:
        - Path=/user/**
        filters:
        - name: HttpPostBodyEnhance
        - name: RequestRateLimiter
          args:
            redis-rate-limiter.replenishRate: 1000
            redis-rate-limiter.burstCapacity: 1000
            redis-rate-limiter.requestedTokens: 1
            key-resolver: '#{@uriKeyResolver}'
        metadata:
          response-timeout: 20000
          connect-timeout: 20000
      - id: product
        uri: http://product.test.com
        predicates:
        - Path=/product/**
        metadata:
          response-timeout: 120000
          connect-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);
   }
   
   // 定义当前谓词所需要用到的参数
   @Validated
   public static class Config {
       private String myField;
   }
   
   @Override
   public List<String> shortcutFieldOrder() {
      // 声明当前谓词参数的传入顺序
      // 参数名要和Config中的参数名称一致
      return Arrays.asList("myField");
   }
   
   // 实现谓词判断的核心方法
   // Gateway会将外部传入的参数封装为Config对象
   @Override
   public Predicate<ServerWebExchange> apply(Config config) {
      return new GatewayPredicate() {
      
         // 在这个方法里编写自定义谓词逻辑
         @Override
         public boolean test(ServerWebExchange exchange) {
            return true;
         }
         
         @Override
         public 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.coloradmin.cn/o/1607191.html

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

相关文章

2024年分享酷我音乐如何下载mp3的方法

这里教大家用酷我音乐小程序的下载方法,小程序下载资源的方法有3种 1.利用专业的抓包工具(Fiddler/Charles)进行获取,然后分析数据包,最后直接用下载器下载分析出来的链接。强烈不推荐,因为大部分人并非程序员出身 2.录屏,录屏效率太慢,所以也不推荐 3. 利用专门的下载资源的…

第49篇:简易处理器<三>

Q&#xff1a;本期我们来设计实现以上介绍的简易处理器&#xff0c;并进行仿真。 A&#xff1a;简易处理器顶层.v文件代码&#xff0c;顶层文件中例化实现处理器的子模块3-8译码器以及寄存器。 仿真示例&#xff1a;DIN (100)8在30 ns时加载到 IR中&#xff0c;而DIN (100)8对…

基于LSTM的负荷预测

长短 期 记 忆 网 络 ( long short term memory&#xff0c; LSTM) &#xff3b;11-12&#xff3d;作为一种特殊的循环神经网络( recurrent neural network&#xff0c;&#xff32;NN) &#xff0c;主要用于解决长序列训 练过程中的梯度消失和梯度爆炸问题。典型的 LSTM 结构如…

高中数学:三角函数之考点精华-对称性相关问题

一、对称性的几种情况 1、1个对称点/对称轴 此种情况&#xff0c;用整体换元法解题 参考&#xff1a;三角函数的整体换元法 2、2个对称点 画图 如果两个对称点之间的距离是a&#xff0c;则函数周期T2a 3、2个对称轴 画图 如果两个对称轴之间的距离是a&#xff0c;则函数…

[Python开发问题] Selenium ERROR: Unable to find a matching set of capabilities

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

【计算机毕业设计】点餐平台网站——后附源码

&#x1f389;**欢迎来到琛哥的技术世界&#xff01;**&#x1f389; &#x1f4d8; 博主小档案&#xff1a; 琛哥&#xff0c;一名来自世界500强的资深程序猿&#xff0c;毕业于国内知名985高校。 &#x1f527; 技术专长&#xff1a; 琛哥在深度学习任务中展现出卓越的能力&a…

天赐和美,大麗和和典藏珍罕翡翠手镯巡礼

翡翠玉镯矜贵难得,从整块质地完美的珍贵原玉中取出,切磨过程往往会造成玉料损耗。色佳、种水细腻且无纹裂的手镯更是难得一见。质素上乘的宝石级翡翠几乎全部产自缅甸,历来珍罕稀有,备受倾慕。大麗和和怀着对翡翠的钟情与对东方气韵的热爱,臻呈「天赐和美」和和典藏缅甸翡翠手镯…

故障诊断 | 基于迁移学习和SqueezeNet 的滚动轴承故障诊断(Matlab)

目录 效果一览基本介绍程序设计参考文献 效果一览 基本介绍 将一维轴承振动信号转换为二维尺度图&#xff08;时频谱图&#xff09;&#xff0c;并使用预训练网络应用迁移学习对轴承故障进行分类。 迁移学习显著减少了传统轴承诊断方法特征提取和特征选择所花费的时间&#xff…

通过实例学C#之FileStream类

简介 可以通过此类进行文件读取。 首先在项目所在文件夹的Bin文件中新建一个test.txt文件&#xff0c;里面输入内容“hello world!”。 构造函数 FileStream (string path, FileMode mode&#xff0c;FileAccess access) 通过路径文件path&#xff0c;打开文件模式mode以及读写…

智能内容分析:Kompas.ai如何揭示内容表现的秘密

在数字营销的世界里&#xff0c;内容分析是衡量内容表现、优化策略并实现营销目标的关键。通过深入分析内容的各项指标&#xff0c;品牌能够更准确地理解其内容的市场表现&#xff0c;从而做出更加明智的营销决策。本文将深入探讨内容分析的重要性&#xff0c;详细介绍Kompas.a…

医疗信创发展走势

2023年&#xff1a;医疗信创的“元年” ----------------------医疗信创的主要任务------------------------ (一) 电脑终端方面 行政办公类电脑终端需支持信创改造&#xff0c;实现“应替尽替真替真用”的目标。 (二) 系统改造方面 1.与诊疗业务无关的信息系统 行政办公…

Navicat导入数据与导出数据

1. 导出数据 * 1. 在表格管理中找打导出向导.* 2. 选择导出格式.* 3. 勾选需要导出的表格(其他设置默认即可).* 4. 选择每张表需要导出的字段(默认即可).* 5. 附加选项(默认即可).* 6. 点击开始.* 7. 默认导出导入到桌面.2. 导入数据 * 0. 先删除原先的表格, 好演示效果. * 1…

CentOS显示mac地址错误|虚拟机克隆|CentOS静态ip

文章目录 怎么复制虚拟机&#xff1f;修改虚拟机静态ip遇到的错误解决 怎么复制虚拟机&#xff1f; 方法一&#xff1a; 方法二&#xff1a; 1.以前创建好的虚拟机所在文件夹复制一份&#xff0c;改名字 2.在虚拟机中打开 后缀为.vmx文件 3.启动虚拟机 修改虚拟机静态ip …

51单片机实验04 -数码管的动态显示实验

目录 一、实验目的 二、实验内容 三、实验原理 四、实验方法 五&#xff0c;实验效果及代码 1&#xff0c;效果 2&#xff0c;代码 六&#xff0c;课后习题 1&#xff0c;使用定时器T0的中断函数1 从999999~0计时 1&#xff09;效果 2&#xff09;代码 2&#xff0c…

OpenHarmony开发实例:【仿桌面应用】

介绍 本示例实现了一个简单桌面应用&#xff0c;实现了以下几点功能&#xff1a; 1.展示了系统安装的应用&#xff0c;实现点击启动、应用上滑弹出卡片、卡片添加到桌面、卡片移除功能。 2.实现桌面数据持久化存储&#xff0c;应用支持卸载、监听应用卸载和安装并显示。 3.…

Arcgis Pro2.5安装教程(内含安装文件)

​最近处理的数据量大&#xff0c;发现arcmap这种老产品属实是不行了&#xff0c;相比于下一代的Arcgis Pro,不但运行速度慢&#xff0c;也容易遇到突然关闭的问题&#xff0c;之前基于团队的选择也没办法&#xff0c;最近实在是被数据搞得无语了&#xff0c;一鼓作气装上了Arc…

武汉星起航:亚马逊上的中国智慧,创新与差异化策略赢得全球赞誉

在全球电商的浪潮中&#xff0c;亚马逊作为行业的佼佼者&#xff0c;为众多商家提供了一个展示自我、实现价值的舞台。在这其中&#xff0c;中国商家以其独特的创新和差异化策略&#xff0c;逐渐在亚马逊平台上崭露头角&#xff0c;赢得了全球消费者的青睐。 中国商家在亚马逊…

新手入门:大语言模型训练指南

在这个信息爆炸的时代&#xff0c;人工智能技术正以前所未有的速度渗透到我们生活的方方面面。从智能手机上的语音助手到自动驾驶汽车&#xff0c;AI的应用无处不在。而在这些令人惊叹的技术背后&#xff0c;大语言模型&#xff08;LLM&#xff09;扮演着至关重要的角色。它们不…

(六)Pandas文本数据 学习简要笔记 #Python #CDA学习打卡

一. 文本数据简介 1&#xff09;定义 指不能参与算术运算的任何字符&#xff0c;也称为字符型数据。如英文字母、汉字、不作为数值使用的数字(以单引号开头)和其他可输入的字符。 文本数据虽不能参加算术运算&#xff0c;但其具有纬度高、量大且语义复杂等特点&#xff0c;因…

企业微信扫码登录遇到的bug及解决办法

企业微信自建应用扫码登录 1.基本配置 1.登录企业微信管理系统&#xff0c;新建一个自建应用 2.点击你新建的应用&#xff0c;拿到AgentId 3.在我的企业页面拿到appid 4.配置可信域名 5.配置授权回调域 写到这&#xff0c;基本配置已完成&#xff0c;可以开始写前端代码 …