SpringCloud-Gateway实现网关

news2024/11/25 1:59:07

网关作为流量的入口,常用的功能包括路由转发、权限校验、限流等

Spring Cloud 是Spring官方推出的第二代网关框架,由WebFlux+Netty+Reactor实现的响应式的API网关,它不能在传统的servlet容器工作,也不能构建war包。基于Filter的方式提供网关的基本功能,例如说安全认证、监控、限流等。

一、功能特征

  • 基于Spring Framework5、Project Reactor和SpringBoot2.0进行构建

  • 动态路由:能够匹配任何请求属性

  • 支持路径重写

  • 集成Spring Cloud服务发现功能(Nacos)

  • 可集成流控降级功能(Sentinel)

  • 可以对路由指定易于编写的Predicate(断言)和Filter(过滤器)

1、路由:

路由是网关中最基础的部分,路由信息包括一个ID、一个目的URI、一组断言工厂、一组Filter组成,如果断言为真,则说明请求的URL和配置的路由匹配。

2、断言:

Java8的断言函数,SpringCloud Gateway中的断言函数类型是Spring5.0框架中的ServerWebExchange。断言函数允许开发者去定义匹配Http request中的任何信息,比如请求头和参数等。

3、过滤器:

SpringCloud Gateway中的Filter分为Gateway Filter和Global Filter。Filter可以对请求和响应进行处理。

官网文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/

二、工作原理

Gateway的工作原理和Zuul的差不多,最大区别就是Gateway的Filter只有pre和post两种。

客户端向Spring Cloud Gateway发出请求,如何请求与网关程序定义的路由匹配,则该请求就会被发送到网关Web处理程序,此时处理程序运行特定的请求过滤器链,过滤器之间用虚线分开的原因是过滤器可能会在发送代理请求的前后处理逻辑。所有pre过滤器逻辑先执行,然后执行代理请求;代理请求完成后,执行post过滤器逻辑组。

本案例未融合Cloud体系,只是使用Gateway网关功能

版本说明:https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E

三、项目案例

  1. pom文件

<?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://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.8</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gateway</name>
    <description>gateway</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-gateway-core -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <version>3.1.5</version>
        </dependency>

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.75.Final</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.26</version>
            <scope>provided</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.16</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.25</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

  1. yml文件

spring:
  application:
    name: spring-cloud-gateway-sample
  cloud:
    gateway:
      routes:
        - id: test
          uri: http://www.baidu.com
          predicates:
            - Path=/api/**
          filters:
            - StripPrefix=1
server:
  port: 9090

启动项目,访问http://localhost:9090/api 会重定向到自己指定的链接

四、路由断言工厂配置

  1. 官方文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

  1. 自定义路由断言工厂

继承 AbstractRoutePredicateFactory 类,重写 apply 方法的逻辑和shortcutFieldOrder方法。

在 apply 方法中可以通过 exchange.getRequest() 拿到 ServerHttpRequest 对象,从而可以获取到请求的参数、请求方式、请求头等信息。

注意事项:类必须是Spring组件;类必须以RoutePredicateFactory作为结尾;类必须继承AbstractRoutePredicateFactory;必须声明静态内部类,声明属性接受配置文件中的信息

@Slf4j
@Component
public class CheckAuthRoutePredicateFactory extends AbstractRoutePredicateFactory<CheckAuthRoutePredicateFactory.Config> {
 
 
    public CheckAuthRoutePredicateFactory() {
        super(Config.class);
        log.info("Loaded RoutePredicateFactory [CheckAuth]");
    }
 
    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("name");
    }
 
 
    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return exchange -> {
            if (config.getName().equals("mengmeng")) {
                return true;
            }
            return false;
        };
    }
 
 
    public static class Config {
 
        private String name;
 
        public void setName(String name) {
            this.name = name;
        }
 
        public String getName() {
            return name;
        }
    }
 
}

五、过滤器工厂配置

1.官方文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories

内置过滤器列表:https://blog.csdn.net/swiftxx/article/details/120545261

2.过滤器有分为三类:

  • 默认过滤器

  • 自定义过滤

  • 全局过滤器

3.过滤器执行顺序:

  • 全局过滤器与其他2类过滤器相比,永远是最后执行的;它的优先级只对其他全局过滤器起作用

  • 当默认过滤器与自定义过滤器的优先级一样时,优先出发默认过滤器,然后才是自定义过滤器;同类型的过滤器,出发顺序与他们在配置文件中声明的顺序一致

  • 默认过滤器与自定义过滤器使用同样的order顺序空间,即他们会按照各自的顺序来进行排序

4.自定义全局过滤器

@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {

    @Autowired
    ObjectMapper objectMapper;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getResponse().getHeaders().getFirst("token");//获取第一个名为token的请求头
        //无权限
        if (StringUtils.isBlank(token)) {
            // 如果消息头中没有 token ,则抛出异常
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
            String result = "";
            try {
                Map<String, Object> map = new HashMap<>(16);
                map.put("code", HttpStatus.UNAUTHORIZED.value());
                map.put("msg", "当前请求未认证,不允许访问");
                map.put("data", null);
                result = objectMapper.writeValueAsString(map);
            } catch (JsonProcessingException e) {
                log.error(e.getMessage(), e);
            }
            DataBuffer buffer = response.bufferFactory().wrap(result.getBytes(StandardCharsets.UTF_8));
            return response.writeWith(Flux.just(buffer));
        }
        //有权限
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        //值越小,越优先执行
        return 1;
    }
}

局部过滤器与全局过滤器区别:

  • 局部:针对某个路由请求

  • 全局:针对所有路由请求

相关链接:https://blog.csdn.net/qq_43437874/article/details/121626379

全局请求日志打印:https://blog.csdn.net/qq_39529562/article/details/108911943

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

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

相关文章

个人开发者如何选择阿里云服务器配置CPU内存带宽?

阿里云服务器个人用怎么选择&#xff1f;云服务器吧建议选择ECS共享型s6&#xff0c;不限制CPU性能&#xff0c;选择1核2G或2核4G都可以&#xff0c;云服务器s6处理器采用2.5 GHz主频的Intel Xeon Platinum 8269CY&#xff08;Cascade Lake&#xff09;&#xff0c;睿频3.2 GHz…

【论文阅读--WSOL】Spatial-Aware Token for Weakly Supervised Object Localization

文章目录方法实验Limitation论文&#xff1a;https://arxiv.org/abs/2303.10438代码&#xff1a;https://github.com/wpy1999/SAT/blob/main/Model/SAT.py方法 这篇文章的方法应该属于FAM这一类。 额外添加的一个spatial token&#xff0c;从第10-12层开始&#xff0c;利用其得…

Vue3技术1之Vue3简介、创建Vue3工程、分析工程结构、安装开发者工具与初识setup

Vue3技术1Vue3简介发展提升创建Vue3工程使用vue-cli创建使用vite创建分析工程结构&#xff08;由vue-cli创建的&#xff09;main.jsvue.config.jsApp.vue安装开发者工具初识setupsetup的两种返回值返回一个对象App.vue返回一个函数App.vueVue2与Vue3混合使用App.vue总结Vue3简介…

【致敬未来的攻城狮计划】— 连续打卡第一天:提前对CPK_RA2E1是瑞萨RA系列开发板的初体验,了解一下(文字上的初理解)

系列文章目录 系列文章目录 前言 一、瑞萨MCU&#xff08;CPK_RA2E1是瑞萨RA系列开发板&#xff09;是什么&#xff1f; 首先引入是什么&#xff1f; 他的优势在哪&#xff1f; 瑞萨CPK_RA2E1 对标stm32 相似之处和不同之处&#xff1f; 瑞萨CPK_RA2E1如何开发&#xff…

集成定时器事件

一&#xff0c;定时器事件 1、概述 libevent提供了高性能定时器的功能&#xff0c;方便执行延迟回调逻辑。在添加事件监听的时候&#xff0c;可以不指定fd和监听的事件&#xff0c;指定超时的时间&#xff0c;实现定时器功能。定时器的实现主要依赖下面的数据结构&#xff0c;…

java 多线程基础 万字详解(通俗易懂)

目录 一、前言 二、定义 1.进程 : 2.线程 : 3.单线程与多线程 : 4.并发与并行 : 三、线程的创建 1.创建线程的两种基本方式 : 1 继承Thread类&#xff0c;并重写run方法 1.5 多线程的执行机制(重要) 2 实现Runnable接口&#xff0c;并重写run方法 2. 两种创建线程方式…

【C++】继承---下(子类默认成员函数、虚继承对象模型的详解等)

前言&#xff1a; 上篇文章我们一起初步了解了继承的概念和使用&#xff0c;本章我们回家新一步深入探讨继承更深层次的内容。 前文回顾——>继承---上 目录 &#xff08;一&#xff09;派生类的默认成员函数 &#xff08;1&#xff09;6个默认成员函数 &#xff08;…

Pytorch全连接神经网络实现手写数字识别

问题Mnist手写数字识别数据集作为一个常见数据集&#xff0c;包含10个类别&#xff0c;在此次深度学习的过程中&#xff0c;我们通过pytorch提供的库函数&#xff0c;运用全连接神经网络实现手写数字的识别方法设置参数input_size 784hidden_size 500output_size 10num_epoc…

JavaScript对象类型之function

目录 一、Function 定义函数 调用函数 默认参数 匿名函数 箭头函数 二、函数是对象 三、函数作用域 四、闭包 五、let、var与作用域 一、Function 定义函数 function 函数名(参数) {// 函数体return 结果; } 例如&#xff1a; function add(a, b) {return a b; …

应届生通过Java培训班转行IT有前途吗?

借用邓小平同志曾说过的一句话&#xff1a;科学技术是第一生产力。IT行业作为科技行业中的一员&#xff0c;不管是在自身的发展&#xff0c;还是支持其他行业的发展中都扮演了不可或缺的角色&#xff0c;“互联网”是社会发展的趋势&#xff0c;前途是无限的。而计算机语言是目…

dolphinscheduler之hivecli 任务

hivecli 任务 Hivecli任务说明 dolphinscheduler的hivecli任务是专门执行hivesql的任务类型。其中子类型分为FROM_SCRIPT和FROM_FILE。 FROM_SCRIPT 执行的脚本可以直接在文本框中编写 执行的底层采用-e参数执行 hive -e "show databases;show tables"FROM_FILE…

建造者模式解读

目录 话题引进 传统方式解决盖房需求 传统方式的问题分析 建造者模式基本介绍 基本介绍 四个角色 原理类图 ​编辑 应用实例 改进代码 建造者模式在 JDK 的应用和源码分析 建造者模式的注意事项和细节 抽象工厂模式 VS 建造者模式 话题引进 1) 需要建房子&#xff1a;…

剑指 Offer (第 2 版)

&#xff08;简单&#xff09;剑指 Offer 03. 数组中重复的数字 找出数组中重复的数字。 在一个长度为 n 的数组 nums 里的所有数字都在 0&#xff5e;n-1 的范围内。数组中某些数字是重复的&#xff0c;但不知道有几个数字重复了&#xff0c;也不知道每个数字重复了几次。请…

Python实现采集某二手房源数据并做数据可视化展示

目录环境介绍&#xff1a;模块使用:实现爬虫思路&#xff1a;代码环境介绍&#xff1a; Python 3.8Pycharm 模块使用: requests >>> pip install requests 数据请求模块 parsel >>> pip install parsel 数据解析模块 csv 内置模块 实现爬虫思路&#x…

如何搭建自己的V Rising自建服务器,以及常见的V Rising服务器问题解决方案

V rising官方服务器经常无法连接&#xff0c;无法和小伙伴玩耍&#xff1b;如何搭建自己的V rising服务器呢&#xff1f;还可以修改掉落倍率&#xff0c;加快游戏进度&#xff0c;搭建自己的私人服务器。 前言 最近V rising这个游戏很火呀&#xff0c;迫不及待地和小伙伴一起…

基于粒子群优化算法的面向综合能源园区的三方市场主体非合作交易方法(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【JSP学习笔记】4.JSP 隐式对象及客户端请求

前言 本章介绍JSP的隐式对象及客户端请求。 JSP 隐式对象 JSP隐式对象是JSP容器为每个页面提供的Java对象&#xff0c;开发者可以直接使用它们而不用显式声明。JSP隐式对象也被称为预定义变量。 JSP所支持的九大隐式对象&#xff1a; 对象描述requestHttpServletRequest 接…

一文吃透Arthas常用命令!

Arthas 常用命令 简介 Arthas 是Alibaba开源的Java诊断工具&#xff0c;动态跟踪Java代码&#xff1b;实时监控JVM状态&#xff0c;可以在不中断程序执行的情况下轻松完成JVM相关问题排查工作 。支持JDK 6&#xff0c;支持Linux/Mac/Windows。这个工具真的很好用&#xff0c;…

【C++】模板进阶--非类型模板参数模板特化及分离编译

文章目录一、非类型模板参数二、模板的特化1.模板特化的概念2.函数模板的特化3.类模板的特化3.1 全特化3.2 偏特化4.类模板特化应用示例三、模板的分离编译四、模板总结一、非类型模板参数 模板参数分为类型形参与非类型形参&#xff0c;其中&#xff0c;类型形参即出现在模板…

MBD-PMSM闭环控制模型(FOC算法)

目录 前面 Speed_and_Position_Estimator 获取HALL信号 HALL状态更新 计算转速 位置判断 ADC相电流/总线电流电压 获取AD值 计算实际值 低速高速切换 SlowLoopControl FastLoopControl 最后 前面 前面分析了BLDC的开环与闭环&#xff0c;接下来分析PMSM或者说FOC…