SpringCloud(八) Gateway网关路由详解

news2025/5/30 22:51:39

目录

一, Gateway服务网关

1.1 为什么需要网关

1.2 网关的实现方式

1.3 Gateway快速入门

1. 创建gateway服务,引入依赖

2. 编写启动类

3. 编写基础配置和路由规则 

4. 重启测试

5. 网关路由的流程图 

6. 总结 

二, Gateway断言工厂

三, 过滤器工厂

3.1 路由过滤器的种类 

1. 请求头过滤器 

2. 默认过滤器 

3. 总结

3.2 全局过滤器

1. 全局过滤器的作用

2. 自定义全局过滤器

3. 过滤器执行的顺序 


SpringCloud Gateway是SpringCloud的一个全新项目,该项目基于Spring 5.0,SpringBoot 2.0,和Project Reactor等响应式编程和事件流技术开发的网关,它旨在为微服务架构提供一种简单有效的统一API路由管理方式.

一, Gateway服务网关

1.1 为什么需要网关

Gateway网关是我们服务的"守门神",所有微服务的同意入口;

网关的核心功能特性:

  • 请求路由
  • 权限控制
  • 限流

架构图:

权限控制:网关作为微服务的入口,需要校验用户是否有请求资格,如果没有进行拦截

路由和负载均衡:一切请求都必须经过gateway,但网关不处理业务,而是根据某种规则,把请求转发到某个微服务,这个过程叫做路由;当然路由的目标服务有多个时,还需要做负载均衡

限流: 当请求流量过高时,在网关中按照下流的微服务能够接受的速度来放行请求,避免服务压力过大

1.2 网关的实现方式

在SpringCloud中网关的实现包括两种:

  • Gateway
  • Zuul

Zuul是基于servlet的实现,属于阻塞式编程,而SpringCloudGateway则是基于Spring5中提供的Wlux,属于响应式编程的实现,具备更好的性能.

1.3 Gateway快速入门

下面,我们演示下网关的基本路由功能,基本步骤如下:

  1. 创建SpringBoot工程gateway,引入网关依赖
  2. 编写启动类
  3. 编写基础配置和路由规则
  4. 启动网关服务进行测试

1. 创建gateway服务,引入依赖

创建服务:

引入服务:

<!--网关-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--nacos服务发现依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

2. 编写启动类

3. 编写基础配置和路由规则 

创建application.yml文件,内容如下:

server:
  port: 10010 # 网关端口
spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求

我们将Path规则的一切请求,都代理到uri参数指定地址;

本例中,我们将/user/**开头的请求,代理到 lb://userservice,lb是负载均衡,根据服务名拉取服务列表,实现负载均衡.

4. 重启测试

重启网关,访问http://localhost:10010/user/1时(因为我们这里设置的网关服务的端口号是10010),复合/user/**规则,请求转发到uri:http://userservice/user/1,得到的结果:

5. 网关路由的流程图 

整个访问流程如下:

6. 总结 

网关搭建步骤:

  • 创建项目,引入nacos服务发现和gateway依赖
  • 配置application.yml,包括服务基本信息,nacos地址(因为网关需要从nacos注册中心拉取服务),路由

路由配置规则:

  • 路由id:路由的唯一标识
  • 路由目标uri:路由的目标地址,http代表固定地址,lb代表根据服务名负载均衡
  • 路由断言predicates:判断路由规则
  • 路由过滤器filters:对请求或响应做处理

二, Gateway断言工厂

我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件,例如 Path=/user/**是按照路径匹配,这个规则是由org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory类来处理的,像这样的断言工厂在SpringCloudGateway还有十几个:

名称说明示例
After是某个时间点后的请求- After=2037-01-20T17:42:47.789-07:00[America/Denver]
Before是某个时间点之前的请求- Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]
Between是某两个时间点之前的请求- Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver]
Cookie请求必须包含某些cookie- Cookie=chocolate, ch.p
Header请求必须包含某些header- Header=X-Request-Id, \d+
Host请求必须是访问某个host(域名)- Host=.somehost.org,.anotherhost.org
Method请求方式必须是指定方式- Method=GET,POST
Path请求路径必须符合指定规则- Path=/red/{segment},/blue/**
Query请求参数必须包含指定参数- Query=name, Jack或者- Query=name
RemoteAddr请求者的ip必须是指定范围- RemoteAddr=192.168.1.1/24
Weight权重处理

我们只需要掌握Path这种路由工程就可以了.

三, 过滤器工厂

GatewayFilter是网关提供的一种过滤器,可以对进入网关的请求和微服务返回的响应结果做处理:

3.1 路由过滤器的种类 

Spring提供了31种不同的路由过滤器工厂,例如:

名称说明
AddRequestHeader给当前请求添加一个请求头
RemoveRequestHeader移除请求中的一个请求头
AddResponseHeader给响应结果中添加一个响应头
RemoveResponseHeader从响应结果中移除有一个响应头
RequestRateLimiter限制请求的流量

1. 请求头过滤器 

下面我们以AddRequestHeader为例来讲解;

需求:给所有进入userservice的请求添加一个请求头:Truth=learning

只需要修改gateway服务的application.yml文件,添加路由头过滤即可:

spring:
  cloud:
    gateway:
      routes:
      - id: user-service 
        uri: lb://userservice 
        predicates: 
        - Path=/user/** 
        filters: # 过滤器
        - AddRequestHeader=Truth, learning # 添加请求头(这里的,的左右两边相当于key和value)

当前过滤器写在userservice路由下,因此仅仅对访问userservice的请求有效.

修改UserController里面的代码获取header:

2. 默认过滤器 

如果要对所有的路由都生效,则可以将过滤器工厂写到default下,格式如下:

spring:
  cloud:
    gateway:
      routes:
      - id: user-service 
        uri: lb://userservice 
        predicates: 
        - Path=/user/**
      default-filters: # 默认过滤项
      - AddRequestHeader=Truth, learning

此时可以发现default-filter是和routes在同一级的.

3. 总结

过滤器的作用是什么?

  • 对路由的请求或响应做加工处理,比如添加请求头
  • 配置在路由下的过滤器只对当前路由的请求生效

default-filter的作用是什么?

  • 对所有路由都生效的过滤器

3.2 全局过滤器

上面提到网关提供了31种过滤器,但每一种过滤器的作用都是固定的,如果我们希望拦截请求,做自己的业务逻辑没办法实现.

1. 全局过滤器的作用

全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与GatewayFilter的作用是一样的,区别在于GatewayFilter通过配置定义,处理逻辑是固定的,而GlobalFilter的逻辑需要自己写代码实现.

定义的方式是实现GlobalFilter接口:

public interface GlobalFilter {
    /**
     *  处理当前请求,有必要的话通过{@link GatewayFilterChain}将请求交给下一个过滤器处理
     *
     * @param exchange 请求上下文,里面可以获取Request、Response等信息
     * @param chain 用来把请求委托给下一个过滤器 
     * @return {@code Mono<Void>} 返回标示当前过滤器业务结束
     */
    Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

在filter中编写自定义逻辑,可以实现以下功能:

  • 登录状态判断
  • 权限校验
  • 请求限流等 

2. 自定义全局过滤器

需求:定义全局过滤器,拦截请求,判断请求的参数是否满足下面条件:

  • 参数中是否有authorization
  • authorization参数值是否是admin

如果同时满足则放行,否则拦截;

实现:

在gateway定义一个过滤器:

@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1.获取请求参数
        MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();
        // 2.获取authorization参数
        String auth = params.getFirst("authorization");
        // 3.校验
        if ("admin".equals(auth)) {
            // 放行
            return chain.filter(exchange);
        }
        // 4.拦截
        // 4.1.禁止访问,设置状态码
        exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
        // 4.2.结束处理
        return exchange.getResponse().setComplete();
    }
}

3. 过滤器执行的顺序 

请求进入网关会碰到三类过滤器:当前路由的过滤器,DefaultFilter,GlobalFilter,请求路由后,会将当前路由过滤器和DefaultFilter,GlobalFilter,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器:

排序的规则是什么呢?

  • 每个路由过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前
  • GlobaFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定
  • 路由过滤器和defaultFilter的order由Spring指定,默认是按照声明顺序从1递增
  • 当过滤器的order值一样时,会按照 defaultFilter > 路由过滤器 > GlobalFilter的顺序执行

详细内容,可以查看源码:

 org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#getFilters()方法是先加载defaultFilters,然后再加载某个route的filters,然后合并;

org.springframework.cloud.gateway.handler.FilteringWebHandler#handle()方法会加载全局过滤器,与前面的过滤器合并后根据order排序,组织过滤器链.

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

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

相关文章

【Mysql】Mysql中表连接的原理

连接简介 在实际工作中&#xff0c;我们需要查询的数据很可能不是放在一张表中&#xff0c;而是需要同时从多张表中获取。下面我们以简单的两张表为例来进行说明。 连接的本质 为方便测试说明&#xff0c;&#xff0c;先创建两个简单的表并给它们填充一点数据&#xff1a; …

【Truffle】三、可视化测试报告的生成

在truffle中&#xff0c;我们可以引入第三方插件&#xff0c;对truffle的测试进行更好的提升&#xff0c;这里介绍两个插件&#xff0c;分别是mocha-junit-reporter和mochawesome两个插件。 一、mocha-junit-reporter插件 mocha-junit-reporter是一个用于Truffle测试框架的插件…

随机森林算法的加速:OpenMP方法

使用OpenMP加速随机森林 前言使用OpenMP对RF训练的加速代码加速效果 对特征重要性评估的加速代码 加速效果附录Windows中使用OpenMPLinux中使用OpenMP 项目主页&#xff1a;randomforest C implementation of random forests classification, regression, proximity and variab…

【德哥说库系列】-Oracle 19C PDB创建大全

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

双绞线(寻线仪,测线仪),光纤测试工具(红光笔,OTDR,光功率计)

网络测试方式&#xff1a; 根据测试中是否向被测网络注入测试流量&#xff0c;可以将网络测试方法分为主动测试和被动测试。 主动测试&#xff1a;利用测试工具有目的地主动问被测网络注入测试流量&#xff0c;根据测试流量的传送情况分析网络技术参数。优点是具备良好的灵活…

读程序员的制胜技笔记03_有用的反模式(上)

1. 教条 1.1. 一成不变的法则 1.2. 这些东西会遮蔽我们的双眼&#xff0c;你坚持相信的时间越久&#xff0c;你被遮蔽双眼的程度也就越深 2. 质疑所有教给你的东西 2.1. 它们有多么有用 2.2. 使用它们的理由 2.3. 使用它们的好处 2.4. 使用它们的代价 3. 反模式 3.1. …

13、Kubernetes核心技术 - Ingress

目录 一、概述 二、Ingress工作原理 三、Ingress 使用 3.1)、Ingress-http方式 3.1.1)、创建Ingress Controller和对应的Service 3.1.2)、创建tomcat的Pod和Service 3.1.3)、创建nginx的Pod和Service 3.1.4)、创建ingress http代理 3.1.5)、配置本地host文件 3.1.6)、…

基于STM32设计的室内环境监测系统(华为云IOT)_2023

一、设计需求 基于STM32+华为云物联网平台设计一个室内环境监测系统,以STM32系列单片机为主控器件,采集室内温湿度、空气质量、光照强度等环境参数,将采集的数据结果在本地通过LCD屏幕显示,同时上传到华为云平台并将上传的数据在Android移动端能够实时显示、查看。 【1…

更新版PHP神算网八字算命星座解梦周易占卜程序源码/PC+H5移动端整站适配/PHP源码带手机版

源码简介&#xff1a; 这个是更新版PHP神算网八字算命星座解梦周易占卜程序源码&#xff0c;能够在PCH5移动端整站适配。作为H5付费算命PHP源码&#xff0c;八字算命网站源码&#xff0c;功能很多强大实用。 2023.3 更新记录&#xff1a; 1、更新了23年属相信息&#xff1b;…

12 pinctrl 和 gpio 子系统

一、pinctrl 子系统 1. 什么是 pinctrl 子系统&#xff1f; 首先回顾一下如何初始化 LED 所使用的 GPIO&#xff1a; ①、修改设备树&#xff0c;添加相应的节点&#xff0c;节点里面重点是设置 reg 属性&#xff0c; reg 属性包括了 GPIO相关寄存器。 ②、获取 reg 属性中 …

基于顺序表实现的可存储性通讯录!!!

基于顺序表实现的通讯录 通讯录的基本功能 顺序表顺序表的部分变量修改修改处一修改处二修改处三 头文件 Contact.h通讯录自定义结构体 功能实现 源文件 Contact.c读取文件中联系人的信息 void ContactReadFile(contact* pcon)保存到文件 void ContactSave(contact* pcon) 测试…

Python:知道什么叫类吗,我这人实在不知道啥叫累。Python类的定义和使用。

前言 在 python 中&#xff0c;对于相同类型的对象进行分类&#xff0c;抽象后&#xff0c;得出共同的特征而形成了类&#xff08;class&#xff09;&#xff0c;面向对象程序设计的关键就是如何合理地定义这些类并且组织多个类之间的关系。 创建类时用变量形式表示对象特征的…

ChinaSoft 论坛巡礼|开源软件供应链论坛

2023年CCF中国软件大会&#xff08;CCF ChinaSoft 2023&#xff09;由CCF主办&#xff0c;CCF系统软件专委会、形式化方法专委会、软件工程专委会以及复旦大学联合承办&#xff0c;将于2023年12月1-3日在上海国际会议中心举行。 本次大会主题是“智能化软件创新推动数字经济与社…

Python基础之列表、元组和字典

一文拿捏Python基本数据类型“列表、数组和字典” 引言 Python中的 列表(英文叫list) 、 元组(英文叫tuple)和字典&#xff08;dictionary&#xff09; 也是 序列 特性的&#xff0c;它们也是非常常用的数据类型。 1、列表&#xff08;List&#xff09; 01、概述 列表&#…

【黑马程序员】SSM框架——SSM整合

文章目录 前言一、SSM 整合1. SSM 整合思路1.1 Spring 整合 MyBatis配置模型数据层标准开发业务层标准开发测试接口事务处理 1.2 Spring 整合 SpringMVCweb 配置类SpringMVC 配置类基于 Restful 的 Controller 开发 2. SSM 整合具体实现2.1 创建工程2.2 SSM 整合SpringMyBatisS…

forward和完美转发

std::move(value)是独立于值的右值引用&#xff0c;一个右值引用参数作为函数的形参&#xff0c;在函数内部再转发该参数的时候已经变成了一个左值&#xff0c;并不是它原来的类型了。 template<typename T> void forwardValue(T& val) {processValue(value); //…

基于STC12C5A60S2系列1T 8051单片机A/D转换器应用

基于STC12C5A60S2系列1T 8051单片机A/D转换器应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍STC12C5A60S2系列1T 8051单片机A/D转换器介绍STC12C5A60S2系列1T 805…

算法题:870. 优势洗牌

该算法是临时想出来的&#xff0c;Java代码的实现在时间上不占优&#xff0c;之后有时间要优化一下&#xff0c;目前就是给大家提供一下思路。 解题思路&#xff1a;田忌赛马的思想 贪心法。 Step1. 对两个数组进行排序。 Step2. 同时遍历排序后的nums2和nums1&#xff0c;将…

RAM和ROM的区别(详解)

RAM和ROM的区别 RAM&#xff08;随机存取存储器&#xff09;和ROM&#xff08;只读存储器&#xff09;都是计算机中常见的存储器类型&#xff0c;它们在计算机系统中有不同的作用和特性。 RAM&#xff08;随机存取存储器&#xff09;&#xff1a; 作用&#xff1a; 用于临时存储…

鸿蒙LiteOs读源码教程+向LiteOS中添加一个简单的基于线程运行时的短作业优先调度策略

一、鸿蒙Liteos读源码教程 鸿蒙的源码是放在openharmony文件夹下&#xff0c;openharmony下的kernel文件夹存放操作系统内核的相关代码和实现。 内核是操作系统的核心部分&#xff0c;所以像负责&#xff1a;资源管理、任务调度、内存管理、设备驱动、进程通信的源码都可以在…