Spring Cloud Gateway(分发请求)

Spring Cloud Gateway 的过滤器和 Spring MVC 的拦截器的区别

过滤器用于整个微服务系统的网关层控制,拦截器则用于单个微服务内部的控制层请求处理。

1. 作用范围
  • Spring Cloud Gateway 过滤器:过滤器的作用范围是在网关层,主要在请求进入后端服务之前和响应返回客户端之前执行。它处理的是网关中的所有流量,可以对来自客户端的请求进行预处理,并决定是否转发给后端服务,适用于微服务架构中的网关场景。

  • Spring MVC 拦截器:拦截器的作用范围是在单个微服务或应用内部的控制层(Controller)请求,作用于处理 HTTP 请求的 Spring MVC 控制器(Controller)之前和之后,主要用于单个服务的请求处理,不适用于跨服务请求的场景。

2. 执行时机
  • 过滤器:过滤器在请求到达后端服务前执行,可以修改请求的路径、请求头、响应头等内容。一般分为 Pre Filter(请求前过滤器)和 Post Filter(响应后过滤器),可以决定是否拦截请求或修改响应内容。过滤器通常对整个网关服务的请求流进行控制,适用于负载均衡、路由分发和限流等。

  • 拦截器:拦截器在单个服务的控制器方法调用前和调用后执行,常用于身份验证、日志记录、会话管理等功能,控制请求在具体 Controller 层的行为。拦截器无法修改网关层的流量请求,也无法对整个微服务系统中的请求流量进行统一管理。

3. 使用场景
  • 过滤器的使用场景

    • 路由:将请求分发到不同的后端微服务。
    • 身份认证和授权:在请求到达后端服务之前对请求进行身份验证或添加认证信息。
    • 限流与熔断:对高并发场景的请求流量进行限流、熔断保护。
    • 日志记录:记录跨服务的请求和响应日志,便于追踪和监控。
    • 添加、修改请求或响应头:在请求进入网关时或响应返回时修改头信息。
  • 拦截器的使用场景

    • 权限检查:在控制器执行前,检查用户的权限是否符合业务要求。
    • 参数验证:在请求到达控制器前,验证请求参数的合法性。
    • 日志记录:记录进入控制器的请求信息和返回结果,用于调试和监控。
    • 异常处理:在请求完成后统一处理和记录异常情况。
4. 配置方式与依赖关系
  • 过滤器:过滤器是 Spring Cloud Gateway 的核心功能,配置在网关服务的 application.yml 中,并且可以配置全局过滤器或局部过滤器,作用于网关中的所有请求或特定的路由路径。它依赖 Spring Cloud Gateway 组件,在网关的微服务架构中使用。

  • 拦截器:拦截器依赖 Spring MVC,在单个 Spring Boot 应用程序中配置和使用。拦截器通常在配置类中进行注册,并通过实现 HandlerInterceptor 接口来自定义拦截逻辑。它不会作用于跨服务的请求,只处理单个服务的请求。

5.总结
特性Spring Cloud Gateway 过滤器Spring MVC 拦截器
作用范围网关层(跨微服务)单个服务
执行时机请求到达后端服务前,响应返回客户端前Controller 调用前后
使用场景路由、限流、认证、修改头信息等权限检查、日志记录、参数验证等
配置方式application.yml 或自定义过滤器类实现 HandlerInterceptor 接口
依赖组件Spring Cloud GatewaySpring MVC

步骤 1:创建网关项目并添加依赖

我们先创建一个 Spring Boot 项目并添加 Spring Cloud Gateway 的依赖。网关的基本配置会依赖这些依赖项。

  1. 创建项目:在 IntelliJ IDEA 或者通过 Spring Initializr 创建一个 Spring Boot 项目。
  2. 添加依赖:在 pom.xml 中引入 Spring Cloud Gateway 依赖。

pom.xml 中,加入以下内容:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Spring Cloud Gateway 依赖提供了核心的网关功能,而 Actuator 依赖可以帮助我们监控和管理网关。

步骤 2:编写启动类

接下来,我们需要一个启动类来运行我们的网关服务。这是一个简单的 Spring Boot 启动类,将帮助我们启动项目。

src/main/java 目录下创建一个 GatewayApplication.java,代码如下:

package com.example.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

启动类 GatewayApplication 的作用是启动 Spring Boot 应用,使网关服务可以监听客户端的请求。

步骤 3:配置基本的路由规则

在网关中,路由规则定义了请求路径和目标服务之间的映射关系。通过这些配置,网关可以根据请求路径将请求转发到不同的微服务。

3.1 创建 application.yml 文件

src/main/resources 目录下创建一个 application.yml 文件,用于定义网关配置。

3.2 定义路由规则

假设我们有三个服务模块:easychat-autheasychat-chateasychat-filesystem。我们希望根据请求路径的不同,将请求转发到相应的服务。

application.yml 中添加以下内容:

server:
  port: 8080  # 设置网关服务的端口

spring:
  cloud:
    gateway:
      routes:
        - id: easychat-auth-route   # 定义路由的ID
          uri: lb://easychat-auth   # 目标服务地址,lb:// 表示使用负载均衡
          predicates:
            - Path=/auth/**         # 当路径匹配 /auth/** 时,将请求转发到 easychat-auth 服务
        - id: easychat-chat-route
          uri: lb://easychat-chat
          predicates:
            - Path=/chat/**
        - id: easychat-filesystem-route
          uri: lb://easychat-filesystem
          predicates:
            - Path=/filesystem/**

配置解释

  • id:为每条路由规则定义一个唯一的 ID,便于管理。
  • uri:目标服务的 URI,这里使用 lb:// 表示服务地址是通过负载均衡机制来解析的。
  • predicates:用于定义路由条件。在这里,我们使用 Path 谓词,通过请求路径来匹配对应的服务模块。

通过这种方式,当网关接收到一个请求时,会检查请求路径:

  • 如果路径匹配 /auth/**,则将请求转发到 easychat-auth 服务。
  • 如果路径匹配 /chat/**,则将请求转发到 easychat-chat 服务。
  • 如果路径匹配 /filesystem/**,则将请求转发到 easychat-filesystem 服务。

步骤 4:配置负载均衡

为了让 lb:// 生效,我们通常需要服务注册中心(比如 Eureka 或 Consul)。在没有服务注册中心的情况下,也可以在 application.yml 中配置静态的负载均衡服务地址。

例如,我们可以指定 easychat-auth 服务的地址为多个实例来模拟负载均衡:

spring:
  cloud:
    gateway:
      routes:
        - id: easychat-auth-route
          uri: lb://easychat-auth
          predicates:
            - Path=/auth/**
    loadbalancer:
      clients:
        easychat-auth:
          instances:
            - http://localhost:8081
            - http://localhost:8082

以上配置中:

  • easychat-auth 的请求会在 localhost:8081localhost:8082 之间进行负载均衡。

步骤 5:配置全局过滤器

过滤器可以用于所有路由(称为全局过滤器),也可以用于特定的路由(称为局部过滤器)。我们从配置全局过滤器开始,举例说明如何记录请求的基本信息,比如请求时间和路径。

application.yml 中,可以配置一个全局过滤器,用于在所有请求经过网关时记录日志。我们可以使用 LoggingFilter 来实现这一功能。

application.yml 文件中添加以下内容:

spring:
  cloud:
    gateway:
      default-filters:
        - name: DedupeResponseHeader    # 移除重复的响应头
          args:
            strategy: RETAIN_FIRST      # 保留第一个重复的响应头
        - name: AddRequestHeader        # 向请求头中添加信息
          args:
            X-Request-Gateway: EasyChatGateway
        - name: RequestRateLimiter      # 基于 Redis 实现的限流器
          args:
            redis-rate-limiter:
              replenishRate: 10         # 每秒允许通过的请求数
              burstCapacity: 20         # 最大突发流量

在这里:

  • DedupeResponseHeader:移除响应中重复的头部信息,防止信息冗余。
  • AddRequestHeader:给请求头添加一个标识 X-Request-Gateway,可以用于标识该请求通过网关。
  • RequestRateLimiter:使用 Redis 实现限流,这里限制每秒允许 10 个请求,突发流量上限为 20。

步骤 6:配置局部过滤器(仅对某些路由生效)

局部过滤器只对特定的路由生效,下面我们给 easychat-auth 路由配置一些常用的过滤器,比如 请求头修改响应头添加

application.yml 中修改 easychat-auth 路由的配置,增加过滤器设置:

spring:
  cloud:
    gateway:
      routes:
        - id: easychat-auth-route
          uri: lb://easychat-auth
          predicates:
            - Path=/auth/**
          filters:
            - AddRequestHeader=X-Auth-Token, "Auth123"   # 添加请求头
            - AddResponseHeader=X-Response-Gateway, "EasyChat-Gateway"  # 添加响应头
            - RewritePath=/auth/(?<segment>.*), /$\\{segment}  # 重写请求路径

解释:

  • AddRequestHeader:在请求头中添加 X-Auth-Token,值为 "Auth123",可以用于认证或日志记录。
  • AddResponseHeader:在响应头中添加 X-Response-Gateway,值为 "EasyChat-Gateway",标识该响应经过了网关。
  • RewritePath:将 /auth/** 的路径重写为 / 后的部分。例如,请求 /auth/login 将重写为 /login,方便后端服务不需要额外处理路径前缀。

步骤 7:自定义过滤器

如果需要更复杂的逻辑,可以编写自定义过滤器。例如,可以创建一个过滤器来记录请求的时间或检查某些请求参数。以下是创建自定义过滤器的步骤:

7.1 创建过滤器类

src/main/java/com/example/gateway/filter 路径下创建一个名为 CustomLoggingFilter.java 的文件:

package com.example.gateway.filter;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class CustomLoggingFilter extends AbstractGatewayFilterFactory<CustomLoggingFilter.Config> {

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

    public CustomLoggingFilter() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            long startTime = System.currentTimeMillis();
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                long endTime = System.currentTimeMillis();
                logger.info("Request to {} took {} ms", exchange.getRequest().getURI(), (endTime - startTime));
            }));
        };
    }

    public static class Config {
        // 配置类可以存放一些自定义配置
    }
}

解释:

  • 该过滤器在请求处理前记录开始时间,然后在响应时计算请求的耗时,并输出到日志。
  • apply() 方法返回的 GatewayFilter 处理请求并记录时间。
7.2 将自定义过滤器应用到某个路由

application.yml 中,将 CustomLoggingFilter 添加到 easychat-chat 路由:

spring:
  cloud:
    gateway:
      routes:
        - id: easychat-chat-route
          uri: lb://easychat-chat
          predicates:
            - Path=/chat/**
          filters:
            - name: CustomLoggingFilter

这样,每次访问 /chat/** 的请求都会触发自定义日志记录,记录请求的处理耗时。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024-11-16-机器学习方法:无监督学习(1) 聚类(上)

文章目录 机器学习方法&#xff1a;无监督学习&#xff08;1&#xff09; 聚类&#xff08;上&#xff09;1. 聚类的基本概念1.1 聚类的概念1.2 聚类的功能1.3 聚类的算法 2. 相似度或距离2.1 闵可夫斯基距离2.2 相关系数2.3 夹角余弦 3 类或簇3.1 类的特征 4 类与类之间的距离…

Vue-组件三大组成组件通信

一、学习目标 1.组件的三大组成部分&#xff08;结构/样式/逻辑&#xff09; scoped解决样式冲突/data是一个函数 2.组件通信 组件通信语法 父传子 子传父 非父子通信&#xff08;扩展&#xff09; 3.综合案例&#xff1a;小黑记事本&#xff08;组件版&#xff09; 拆…

Scratch 014生日贺卡(上)

知识回顾&#xff1a; 1、“面向鼠标指针”积木块 2、“重复执行直到”积木块 本次分享制作生日贺卡引入广播模块 案列效果&#xff1a; 生日贺卡上案例效果-CSDN直播 步骤拆解&#xff1a; 1、添加背景和角色 2、编辑贺卡造型添加名字 3、流程图的组成和画法 4、…

MySQL中将一个字符串字段按层级树状展开

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 文章目录 需求1.分析2.实现3.思路刨析表结构和数据 需求 数据库中有个字段如下 如何将其转换为如下形式&#xff1a; 1.分析 1.他的层级个数是不确定的&#xff0c;也就是说有的有2层有的有5…

hive搭建

1.准备环境 三台节点主机已安装hadoopmysql数据库 2.环境 2.1修改三台节点上hadoop的core-site.xml <!-- 配置 HDFS 允许代理任何主机和组 --> <property><name>hadoop.proxyuser.hadoop.hosts</name><value>*</value> </property&…

创建vue+electron项目流程

一个vue3和electron最基本的环境搭建步骤如下&#xff1a;// 安装 vite vue3 vite-plugin-vue-setup-extend less normalize.css mitt pinia vue-router npm create vuelatest npm i vite-plugin-vue-setup-extend -D npm i less -D npm i normalize.css -S &#xff0…

Pyhon基础数据结构(列表)【蓝桥杯】

a [1,2,3,4,5] a.reverse() print("a ",a) a.reverse() print("a ",a)# 列表 列表&#xff08;list&#xff09;有由一系列按照特定顺序排序的元素组成 列表是有顺序的&#xff0c;访问任何元素需要通过“下标访问” 所谓“下标”就是指元素在列表从左…

帽子矩阵--记录

帽子矩阵&#xff08;Hat Matrix&#xff09;并不是由某一位具体的科学家单独发明的&#xff0c;而是逐渐在统计学和线性代数的发展过程中形成的。帽子矩阵的概念最早出现在20世纪初的统计学文献中&#xff0c;尤其是在回归分析的研究中得到了广泛应用。然而&#xff0c;具体是…

一.安装版本为19c的Oracle数据库管理系统(Oracle系列)

1.数据库版本信息&#xff1a; 版本信息&#xff1a; 或者直接由命令查出来&#xff1a; 2.操作系统的版本信息 3.安装包下载与上传 可以去oracle官网下载也可以从其他人的百度网盘链接中下载&#xff1a; 使用xftp工具或者其他的工具&#xff08;mobaxterm&#xff09;上传到l…

计算机视觉 ---图像模糊

1、图像模糊的作用&#xff1a; 减少噪声&#xff1a; 在图像获取过程中&#xff0c;例如通过相机拍摄或者传感器采集&#xff0c;可能会受到各种因素的干扰&#xff0c;从而引入噪声。这些噪声在图像上表现为一些孤立的、不符合图像主体内容的像素变化&#xff0c;如椒盐噪声&…

关于强化学习的一份介绍

在这篇文章中&#xff0c;我将介绍与强化学习有关的一些东西&#xff0c;具体包括相关概念、k-摇臂机、强化学习的种类等。 一、基本概念 所谓强化学习就是去学习&#xff1a;做什么才能使得数值化的收益信号最大化。学习者不会被告知应该采取什么动作&#xff0c;而是必须通…

嵌入式硬件杂谈(二)-芯片输入接入0.1uf电容的本质(退耦电容)

引言&#xff1a;对于嵌入式硬件这个庞大的知识体系而言&#xff0c;太多离散的知识点很容易疏漏&#xff0c;因此对于这些容易忘记甚至不明白的知识点做成一个梳理&#xff0c;供大家参考以及学习&#xff0c;本文主要针对芯片输入接入0.1uf电容的本质的知识点的进行学习。 目…

近几年新笔记本重装系统方法及一些注意事项

新笔记本怎么重装系统&#xff1f; 近几年的新笔记本默认开启了raid on模式或vmd选项&#xff0c;安装过程中会遇到问题&#xff0c;新笔记本电脑重装自带的系统建议采用u盘方式安装&#xff0c;默认新笔记本有bitlocker加密机制&#xff0c;如果采用一键重装系统或硬盘方式安装…

GPIO相关的寄存器(重要)

目录 一、GPIO相关寄存器概述 二、整体介绍 三、详细介绍 1、端口配置低寄存器&#xff08;GPIOx_CRL&#xff09;&#xff08;xA...E&#xff09; 2、端口配置高寄存器&#xff08;GPIOx_CRH&#xff09;&#xff08;xA...E&#xff09; 3、端口输入数据寄存器&#xff…

华为Mate 70临近上市:代理IP与抢购攻略

随着科技的飞速发展&#xff0c;智能手机已经成为我们日常生活中不可或缺的一部分。而在众多智能手机品牌中&#xff0c;华为一直以其卓越的技术和创新力引领着行业的发展。近日&#xff0c;华为Mate 70系列手机的发布会正式定档在11月26日&#xff0c;这一消息引发了众多科技爱…

NVR录像机汇聚管理EasyNVR多品牌NVR管理工具视频汇聚技术在智慧安防监控中的应用与优势

随着信息技术的快速发展和数字化时代的到来&#xff0c;安防监控领域也在不断进行技术创新和突破。NVR管理平台EasyNVR作为视频汇聚技术的领先者&#xff0c;凭借其强大的视频处理、汇聚与融合能力&#xff0c;展现出了在安防监控领域巨大的应用潜力和价值。本文将详细介绍Easy…

MySQL:表设计

表的设计 从需求中获得类&#xff0c;类对应到数据库中的实体&#xff0c;实体在数据库中表现为一张一张的表&#xff0c;类中的属性就对应着表中的字段&#xff08;也就是表中的列&#xff09; 表设计的三大范式&#xff1a; 在数据库设计中&#xff0c;三大范式&#xff0…

单元测试时报错找不到@SpringBootConfiguration

找到问题出现原因&#xff1a; 错误表示 Spring Boot 在运行测试时无法找到 SpringBootConfiguration 注解。 通常&#xff0c;SpringBootTest注解用于加载 Spring Boot 应用上下文&#xff0c;但它需要找到一个带有SpringBootConfiguration&#xff08;或者Configuration&am…

Python爬虫下载新闻,Flask展现新闻(2)

上篇讲了用Python从新闻网站上下载新闻&#xff0c;本篇讲用Flask展现新闻。关于Flask安装网上好多教程&#xff0c;不赘述。下面主要讲 HTML-Flask-数据 的关系。 简洁版 如图&#xff0c;页面简单&#xff0c;主要显示新闻标题。 分页&#xff0c;使用最简单的分页技术&…

信捷PLC转以太网连接电脑方法

信捷XC/XD/XL等系列PLC如何上下载程序?可以选择用捷米特JM-ETH-XJ模块轻松搞定,并不需要编程&#xff0c;即插即用&#xff0c;具体看见以下介绍&#xff1a; 产品介绍 捷米特JM-ETH-XJ是专门为信捷PLC转以太网通讯面设计&#xff0c;可实现工厂设备信息化需求&#xff0c;对…