SpringCloud-Gateway实现网关

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

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

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

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

相关文章

​破除“内卷”,什么才是高阶智能座舱更优方案?

下一代智能座舱雏形已现。 从多屏互动到舱内全场景交互&#xff0c;从中控娱乐快速延伸到更多元化的车内娱乐平台&#xff1b;越来越多元化功能集中上车&#xff0c;座舱空间的营造&#xff08;包括氛围灯、香氛等&#xff09;以及AR技术的应用等等&#xff0c;开始深刻影响着…

关于ROS机器人-文心一言和CatGPT怎么看-

交流截图&#xff1a; 文字版本如下&#xff08;W-文心&#xff1b;C-猿如意&#xff09;&#xff1a; 如何通过蓝桥云课学习ROS机器人&#xff1f; W&#xff1a; 如果你想通过蓝桥云课学习ROS机器人&#xff0c;可以按照以下步骤进行&#xff1a; 确认ROS机器人的版本和教…

能自动翻译的软件-最精准的翻译软件

批量翻译软件是一种利用自然语言处理技术和机器学习算法&#xff0c;可以快速翻译大量文本内容的工具。批量翻译软件可以处理多种格式的文本&#xff0c;包括文档、网页、邮件、PDF等等&#xff0c;更符合掌握多语言的计算机化需求。 147CGPT翻译软件特点&#xff1a; 1.批量任…

opencv:介绍 SIFT(尺度不变特征变换)及其使用(一)

在本章中 我们将了解 SIFT 算法的概念 我们将学习如何找到 SIFT 关键点和描述符。 理论 在过去的几章中,我们了解了一些角点检测器,如 Harris 等。它们具有旋转不变性,这意味着即使图像旋转,我们也可以找到相同的角点。这是显而易见的,因为旋转后的图像中的角点仍然是角点…

(链表专题) 328. 奇偶链表 ——【Leetcode每日一题】

328. 奇偶链表 给定单链表的头节点 head &#xff0c;将所有索引为奇数的节点和索引为偶数的节点分别组合在一起&#xff0c;然后返回重新排序的列表。 第一个 节点的索引被认为是 奇数 &#xff0c; 第二个 节点的索引为 偶数 &#xff0c;以此类推。 请注意&#xff0c;偶…

腾讯云轻量应用服务器搭建网站教程(WordPress为例)

腾讯云轻量应用服务器搭建WordPress网站教程&#xff0c;先安装WordPress应用镜像&#xff0c;然后远程连接轻量应用服务器获取WP用户名和密码&#xff0c;域名DNS解析到轻量服务器IP地址&#xff0c;登陆WordPress后台管理全过程&#xff0c;腾讯云百科来详细说下腾讯云轻量服…

弹塑性力学--应变硬化

在单轴拉伸试验中&#xff0c;当应力超过屈服强度后&#xff0c;需要施加更大的载荷产生更大的应力&#xff0c;才会使材料发生更多的塑性变形。随着塑性应变的增加&#xff0c;材料变得更强、更难以变形了&#xff0c;因此这个阶段称为“应变硬化”&#xff08;Strain Hardeni…

Vue语法糖<script setup>详解,用最快的方式让你看懂和<script>的区别

前言 Vue3出来已经3年了&#xff0c;但是前两天在百度上搜索有关setup语法糖的细节时&#xff0c;发现很多博客关于语法糖细节部分&#xff0c;还是讲的很粗糙&#xff0c;因此决定自己来写一篇入门的博客&#xff0c;方便大家快速上手。 <script setup>简介 它是Vue3…

项目沟通管理流程的6大规范步骤

1、建立沟通计划 需要对整个项目的沟通对象、沟通内容、沟通频率、沟通方法等各方面&#xff0c;进行计划和安排。尤其需明确沟通机制&#xff0c;建立完整的沟通计划。并根据项目沟通的具体情况&#xff0c;实时添加和修订计划&#xff0c;以保证沟通管理计划的持续适用性。 项…

拐点!智能座舱破局2023

“这是我们看到的整个座舱域控渗透率&#xff0c;2022年是8.28%&#xff0c;主力的搭载车型仍然是30-35万区间。”3月29日&#xff0c;2023年度&#xff08;第五届&#xff09;高工智能汽车市场峰会上&#xff0c;高工智能汽车研究院首发《2022-2025年中国智能汽车产业链市场数…

每日学术速递4.11

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.InstantBooth: Personalized Text-to-Image Generation without Test-Time Finetuning 标题&#xff1a;InstantBooth&#xff1a;无需测试时间微调的个性化文本到图像生成 作者&a…

HTTP HTTPS简介

一篇文章带你走进HTTP HTTPS场景复现核心干货HTTP/HTTPS简介&#xff08;简单比较&#xff09;HTTP工作原理HTTPS作用场景复现 最近在对前端的深入学习过程中&#xff0c;接触到了与网络请求相关的内容&#xff0c;于是打算出一个专栏&#xff0c;从HTTP与HTTPS入手&#xff0…

基于t-SNE的Digits数据集降维与可视化

基于t-SNE的Digits数据集降维与可视化 描述 t-SNE(t-分布随机邻域嵌入)是一种基于流形学习的非线性降维算法&#xff0c;非常适用于将高维数据降维到2维或者3维&#xff0c;进行可视化观察。t-SNE被认为是效果最好的数据降维算法之一&#xff0c;缺点是计算复杂度高、占用内存…

运行时内存数据区之程序计数器

内存是非常重要的系统资源&#xff0c;是硬盘和CPU的中间仓库及桥梁&#xff0c;承载着操作系统和应用程序的实时选行。JVM内存布局规定了Java在运行过程中内存申请、分配、管理的策略&#xff0c;保证了JVM的高效稳定运行。 不同的VM对于内存的划分方式和管理机制存在着部分差…

英特尔CEO基辛格:开创可持续计算新时代

近日&#xff0c;帕特基辛格作为英特尔CEO后&#xff0c;第一次来华访问。在2023英特尔可持续发展高峰论坛上&#xff0c;笔者有幸聆听他的演讲。他严谨又不乏幽默地给我们分享了英特尔如何践行可持续发展的思考和举措。 基辛格表示&#xff0c;身处科技行业&#xff0c;我们不…

DeepFM论文翻译

1.摘要 为了最大化推荐系统的CTR&#xff0c;学习用户行为的复杂交叉特征很关键。 尽管有很大进步&#xff0c;现有的方法无论对低阶还是高阶的交叉特征&#xff0c;似乎还是有很强的bias, 或者需要专门的特征工程。 本文&#xff0c;我们证明了得出一个能强化高阶和低阶交叉特…

钢网是SMT生产使用的一种工具,如何制作?

钢网是SMT生产使用的一种工具&#xff0c;其主要功能是将锡膏准确地涂敷在有需要焊接的PCB焊盘上。 钢网的好坏&#xff0c;直接影响印刷工作的质量&#xff0c;目前一般使用的金属钢网&#xff0c;是由薄薄的、带有小孔的金属板制作成的&#xff0c;在开孔处&#xff0c;锡膏…

记录网关zuul处理跨域/XSS问题

一&#xff0c;疑问 1.之前遇到跨域问题是在NG中解决的&#xff0c;添加跨域请求头和域名配置。那么与网关处理跨域问题关系是什么&#xff0c;NG处理了&#xff0c;为什么还需要在网关中处理 二&#xff0c;前置知识 zuul概念与原理 zuul 的概念和原理 - 知乎 Zuul工作原…

全球首个完全开源的指令跟随大模型;T5到GPT-4最全盘点

1. Dolly 2.0&#xff1a;世界上第一个完全开源的指令跟随LLM 两周前&#xff0c;Databricks发布了类ChatGPT的大型语言模型 (LLM)Dolly&#xff0c;其训练成本不到 30 美元。今天&#xff0c;他们发布了 Dolly 2.0&#xff0c;这是业内第一个开源的指令跟随LLM&#xff0c;并根…

gdb 跟踪调式core

自己编译的问题出现段错误: 编译:使用gdb调试core文件来查找程序中出现段错误的位置时,要注意的是可执行程序在编译的时候需要加上-g编译命令选项。 gdb调试core文件的步骤 gdb调试core文件的步骤常见的有如下几种,推荐第一种。 具体步骤一: (1)启动gdb,进入core文…