Springcloud之gateway的使用详解

news2024/11/14 15:06:33

官网地址:https://docs.spring.io/spring-cloud-gateway/docs/4.0.4/reference/html/

1.网关入门 helloword

网关不依赖start-web

导入的pom:

<!--gateway-->
<dependency>
    <groupIdorg.springframework.cloud</groupId>
    <artifactIdspring-cloud-starter-gateway</artifactId>
    <exclusions>
        <exclusion>
            <groupIdorg.springframework.boot</groupId>
            <artifactIdspring-boot-starter-web</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupIdcom.alibaba.cloud</groupId>
    <artifactIdspring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 指标监控健康检查的actuator,网关是响应式编程删除掉spring-boot-starter-web dependency-->
<dependency>
    <groupIdorg.springframework.boot</groupId>
    <artifactIdspring-boot-starter-actuator</artifactId>
</dependency>
<!--lombok-->
<dependency>
    <groupIdorg.projectlombok</groupId>
    <artifactIdlombok</artifactId>
    <version1.18.28</version>
    <scopeprovided</scope>

配置文件:

 server:
  port: 8085

spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      routes:
        #路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名
        - id: order-service
          #匹配后提供服务的路由地址
          uri: http://localhost:8081/
          #uri: http://cloud-payment-service                #匹配后提供服务的路由地址
          # 断言,路径相匹配的进行路由
          predicates:
            - Path=/order/getOrder

直接访问网关服务+网关端口-》

http://localhost:8085/order/getOrder

最后服务转发到8081服务对应的接口上

2.使用服务名的方式调用网关

正常我们会使用服务名的方式进行服务间的调用

不会使用端口号的形式,不然端口号的变更很难维护

变更配置文件

引入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

变更配置文件

server:
  port: 8085

spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      routes:
        #路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名
        - id: order-service
          #匹配后提供服务的路由地址
          uri: lb://order-service
          #uri: http://cloud-payment-service                #匹配后提供服务的路由地址
          # 断言,路径相匹配的进行路由
          predicates:
            - Path=/order/getOrder

3.常用的内置Route Predicate

是什么?

Spring Cloud Gateway包含许多内置的路由谓词工厂。 所有这些谓词都匹配HTTP请求的不同属性。 您可以使用逻辑 and 语句来联合组合多个路由谓词工厂。

在gateway服务启动的时候会看到这样的日志

After,before....

Gateway 启动的时候会加载默认的谓词工厂

1.Predicate之After

配置文件变更:

server:
  port: 8085

spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      routes:
        #路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名
        - id: order-service
          #匹配后提供服务的路由地址
          uri: lb://order-service
          #uri: http://cloud-payment-service                #匹配后提供服务的路由地址
          # 断言,路径相匹配的进行路由
          predicates:
            - Path=/order/getOrder
            - After=2023-07-07T22:14:00.583857100+08:00[Asia/Shanghai]

局部变更

- After=2023-07-07T22:14:00.583857100+08:00[Asia/Shanghai]

after用于限定请求的处理时间,只有在指定时间之后的请求才会被匹配并路由。给出的配置:

生成时间的方式:

public class DateUtil {

    public static void main(String[] args) {
        System.out.println(ZonedDateTime.now());
    }
}
结果:2024-07-07T22:09:45.583857100+08:00[Asia/Shanghai]

应用场景:

举个例子:抢茅台,设置茅台开始抢购的时间

只有到该时间之后接口才会有效,否则一直404

4.Predicate之Cookie

包含cookie且值匹配

  • Cookie=username,zhangsan

配置如下:

server:
  port: 8085

spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      routes:
        #路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名
        - id: order-service
          #匹配后提供服务的路由地址
          uri: lb://order-service
          #uri: http://cloud-payment-service                #匹配后提供服务的路由地址
          # 断言,路径相匹配的进行路由
          predicates:
            - Path=/order/getOrder
            - After=2024-07-07T22:14:00.583857100+08:00[Asia/Shanghai]
            #- Before=2023-07-08T21:09:00.583857100+08:00[Asia/Shanghai]
            - Cookie=username,zhangsan

精确匹配,匹配不到404

4.Predicate之Header

配置如下

predicates:
  - Path=/order/getOrder
  - After=2024-07-07T22:14:00.583857100+08:00[Asia/Shanghai]
  #- Before=2023-07-08T21:09:00.583857100+08:00[Asia/Shanghai]
  - Cookie=username,zhangsan
  #- Header=X-Request-Id=123456  \d+  #请求头要有X-Request-Id且值正整数的正表达式
  

如果输入的是字符串404

- Host=**.css.com

请求头包含任意值后缀是css.com的域名

4.Predicate之Query Route 谓词工厂

指定请求里必须包含参数,允许正则表达式

  • - Query=username,\d+ 要有参数名username并且必须是整数

  • - RemoteAddr=192.168.124.1/24 # 外部访问我的ip限制,最大跨度不超过32,目前是1-24-

  • - Method=

4.自定义predicate

gateway的谓词断言和原生的写法很类似,照葫芦画瓢,参考源码。

新建一个自定义的路由断言工厂,格式和源码格式一样

参考After谓词 源码如下:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.springframework.cloud.gateway.handler.predicate;

import jakarta.validation.constraints.NotNull;
import java.time.ZonedDateTime;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
import org.springframework.web.server.ServerWebExchange;

public class AfterRoutePredicateFactory extends AbstractRoutePredicateFactory<AfterRoutePredicateFactory.Config> {
    public static final String DATETIME_KEY = "datetime";

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

    public List<String> shortcutFieldOrder() {
        return Collections.singletonList("datetime");
    }

    public Predicate<ServerWebExchange> apply(AfterRoutePredicateFactory.Config config) {
        return new GatewayPredicate() {
            public boolean test(ServerWebExchange serverWebExchange) {
                ZonedDateTime now = ZonedDateTime.now();
                return now.isAfter(config.getDatetime());
            }

            public Object getConfig() {
                return config;
            }

            public String toString() {
                return String.format("After: %s", config.getDatetime());
            }
        };
    }

    public static class Config {
        @NotNull
        private ZonedDateTime datetime;

        public Config() {
        }

        public ZonedDateTime getDatetime() {
            return this.datetime;
        }

        public void setDatetime(ZonedDateTime datetime) {
            this.datetime = datetime;
        }
    }
}

Config 内部类对应yaml文件里的配置,咱们在配置After的时候使用的是

  • After=time.....

这里要变更成我们自己的pridicate这里的配置就可以按照我们自己定义的规则配置。

gateway支持两种配置方式

  • 1.Shortcut Configuration

  • 2.Fully Expanded Arguments

方式一最简单

比如

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - Cookie=mycookie,mycookievalue

方式二

写法参考下面这种方式

Args key value

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - name: Cookie
          args:
            name: mycookie
            regexp: mycookievalue

官网地址:docs.spring.io/spring-cloud-gateway/docs/4.0.4/reference/html

假设业务场景:

有这样一个业务场景,请求参数里面必须包含一个参数为userType的参数,该参数代表着用户的会员等级,只有会员等级为gold的才可以访问。

代码实现

package com.css.tom.mypridicate;

import lombok.Getter;
import lombok.Setter;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

import java.util.function.Predicate;

/**
 * @author weiwensi
 * @version 1.0-SNAPSHOT
 * @since 2024/7/8 21:49
 */
@Component
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {

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

    @Override
    public Predicate<ServerWebExchange> apply(MyRoutePredicateFactory.Config config) {
        return new Predicate<ServerWebExchange>() {
            //serverWebExchange 这个参数 相当于servlet的request
            @Override
            public boolean test(ServerWebExchange serverWebExchange) {
                String userType = serverWebExchange.getRequest().getQueryParams().getFirst("userType");
                if (userType == null) {
                    return false;
                }
                //如果说参数存在,就和Config进行比较
                if(userType.equalsIgnoreCase(config.getUserType())){
                    return true;
                }
                return false;
            }
        };
    }

    //这个Config类就是我们的路断言规则,很重要
    public class Config {
        @Setter
        @Getter
        private String userType; //对应会员等级 /钻石,金牌,银牌
    }
}

配置文件配置(Fully方式)

    - name: My
       args:
            userType: diamond
           

如果使用shortcut的方式自定义实现代码里参考After的

 public List<String> shortcutFieldOrder() {
        return Collections.singletonList("datetime");
    }

增加如下代码:

 public List<String> shortcutFieldOrder() {
        return Collections.singletonList("userType");
    }

完整代码:

package com.css.tom.mypridicate;

import lombok.Getter;
import lombok.Setter;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;

/**
 * @author weiwensi
 * @version 1.0-SNAPSHOT
 * @since 2024/7/8 21:49
 */
@Component
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {

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

    @Override
    public List<String> shortcutFieldOrder() {
        return Collections.singletonList("userType");
    }
    @Override
    public Predicate<ServerWebExchange> apply(MyRoutePredicateFactory.Config config) {
        return new Predicate<ServerWebExchange>() {
            //serverWebExchange 这个参数 相当于servlet的request
            @Override
            public boolean test(ServerWebExchange serverWebExchange) {
                String userType = serverWebExchange.getRequest().getQueryParams().getFirst("userType");
                if (userType == null) {
                    return false;
                }
                //如果说参数存在,就和Config进行比较
                if(userType.equalsIgnoreCase(config.getUserType())){
                    return true;
                }
                return false;
            }
        };
    }

    //这个Config类就是我们的路断言规则,很重要
    public class Config {
        @Setter
        @Getter
        private String userType; //对应会员等级 /钻石,金牌,银牌
    }
}

5.gateway过滤器

类型

  • 全局默认过滤器 Global Filters

  • 单一内置过滤器 GatewayFilter

  • 自定义过滤器

官网地址:docs.spring.io/spring-cloud-gateway/docs/current/reference/html#global-filters

gateway内置过滤器

docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories

38个 分组

  • RequestHeader 相关组

  • 请求参数 Requestparameter 相关组

  • 回应头 ResponseHeader 相关组

  • 前缀和路径相关组

  • 其他

配置文件配置

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

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

相关文章

CKS-Kubernetes-证书题库总结

证书如下 个人考试总结 第一次考试 成绩如下&#xff0c;其实这一次我题目全做了&#xff0c;个人感觉也没有什么错误&#xff0c;但是环境做错了 7月14日CKS考试笔记 问题分析 你这次考试得了57%。 至少需要67%的分数才能通过。 对您完成的考试的自动分析显示了三个得分最…

【深度学习】起源:人脑的神经结构

文章目录 睁眼看世界&#xff0c;倾耳听人间脑子&#xff0c;是个好东西&#xff01;眼睛成像其它身体感触系统脑子&#xff1a;我很忙的&#xff01;脑细胞&#xff1a;脑子里的打工人生物神经元——结构生物神经元——人脑的运算单位 人脑的深度学习总结 睁眼看世界&#xff…

数据结构 —— B树

数据结构 —— B树 B树B树的插入操作分裂孩子分裂父亲分裂 我们之前学过了各种各样的树&#xff0c;二叉树&#xff0c;搜索二叉树&#xff0c;平衡二叉树&#xff0c;红黑树等等等等&#xff0c;其中平衡二叉树和红黑树都是控制树的高度来控制查找次数。 但是&#xff0c;这都…

李彦宏论AI:技术革新与产业价值的双重驱动

文章目录 每日一句正能量前言AI技术应用场景探索1. **医疗健康**2. **自动驾驶**3. **工业制造**4. **金融服务**5. **教育**6. **农业**7. **环境监测**8. **安全监控**9. **零售业**10. **艺术与娱乐** 避免超级应用陷阱的策略1. **明确应用目标**2. **优化用户体验**3. **注…

NFT革命:数字资产的确权、营销与元宇宙的未来

目录 1、NFT&#xff1a;数字社会的数据确权制度 2、基于低成本及永久产权的文化发现 3、PFP&#xff1a;从“小图片”到“身份表达”&#xff0c;再到社区筛选 4、透明表达&#xff1a;NFT 在数字化营销中的商业价值 5、可编程性&#xff1a;赋予 NFT 无限可能的应用 5.…

/秋招突击——7/21——复习{堆——数组中的第K大元素}——新作{回溯——全排列、子集、电话号码的字母组合、组合总和、括号生成}

文章目录 引言复习数组中的第K大的最大元素复习实现参考实现 新作回溯模板46 全排列个人实现参考实现 子集个人实现参考实现 电话号码的字母组合复习实现 组合总和个人实现参考实现 括号生成复习实现 总结 引言 昨天的科大讯飞笔试做的稀烂&#xff0c;今天回来好好练习一下&a…

git实操之线上分支合并

线上分支合并 【 1 】本地dev分支合并到本地master上 # 本地dev分支合并到本地master上# 远程(线上)分支合并# 本地dev分支合并到本地master上# 远程(线上)分支合并#####本地和线上分支同步################ #### 远程创建分支&#xff0c;拉取到本地####-远程创建分支&#…

服务攻防-应用协议cve

Cve-2015-3306 背景&#xff1a; ProFTPD 1.3.5中的mod_copy模块允许远程攻击者通过站点cpfr和site cpto命令读取和写入任意文件。 任何未经身份验证的客户端都可以利用这些命令将文件从文件系统的任何部分复制到选定的目标。 复制命令使用ProFTPD服务的权限执行&#xff0c;…

《2024 年 7 月 17 日最新开发者服务 API 推荐》

在当今的数字货币领域&#xff0c;对代币持有信息的精准洞察至关重要。而 Bitquery 代币持有信息查询 API 接口的出现&#xff0c;为开发者和投资者提供了强大的工具。无论是想要揭示代币趋势&#xff0c;检测虚假交易&#xff0c;发现热门代币&#xff0c;还是评估代币财富差距…

查找算法③-斐波那契查找算法/黄金分割查找算法

一、算法原理 斐波那契查找算法又称黄金分割查找算法&#xff0c;它是在二分查找基础上根据斐波那契数列进行分割的一种衍生算法&#xff0c;简单来说&#xff0c;二分查找是一分为二进行查找&#xff0c;斐波那契查找是使用斐波那契数列进行分割查找。而斐波那契数列就是我们通…

【Dison夏令营 Day 26】PyGame 中的赛车游戏

在本文中&#xff0c;我们将了解如何使用 Pygame 在 Python 中创建一个赛车游戏。在这个游戏中&#xff0c;我们将拥有驾驶、障碍物碰撞、通过关卡时速度增加、暂停、倒计时、记分牌和说明书屏幕等功能。 所需模块&#xff1a; 在继续之前&#xff0c;请在命令提示符下运行以下…

百科词条可以删除吗?删除百科词条的方法

大多时候大家都是想创建百度词条&#xff0c;然而有时候也会需要删除某些词条&#xff0c;因为其内容有错误、不实或者涉及某些敏感信息。但是百科词条删除需要非常明确的理由&#xff0c;不然也是很难通过的&#xff0c;这里小马识途百科顾问先初步分享下删除百科词条的流程。…

一套C#语言开发的医学影像归档与通讯系统PACS源码,三甲以下医院都能满足

医学影像归档与通讯系统&#xff08;PACS&#xff09;系统&#xff0c;是一套适用于从单一影像设备到放射科室、到全院级别等各种应用规模的医学影像归档与通讯系统。PACS集患者登记、图像采集、存档与调阅、报告与打印、查询、统计、刻录等功能为一体&#xff0c;有效地实现了…

Logstash docker发布

一 下载Logstash 不废话了&#xff0c;我下载的7.17.6 二 新增配置文件 在logstash/pipeline中&#xff0c;添加logstash.conf input {jdbc { # 连接jdbc_connection_string > "jdbc:mysql://192.168.1.1:3306/kintech-cloud-bo&#xff1f;characterEncodingUTF-8&…

【Linux网络】套接字编程

本篇博客整理了 socket 套接字编程的相关内容&#xff0c;包括 socket 网络通信原理、socket 相关的系统调用接口等&#xff0c;分别演示了基于UDP协议、TCP协议的 socket 网络编程&#xff0c;旨在让读者更加深入理解网络通信原理和设计&#xff0c;对网络编程有初步的认识和掌…

ECCV2024中有哪些值得关注的扩散模型相关的工作?

Diffusion Models专栏文章汇总:入门与实战 The Fabrication of Reality and Fantasy: Scene Generation with LLM-Assisted Prompt Interpretation 本文探讨了如何利用扩散模型生成需要艺术创造力或专业知识的复杂和富有想象力的图像提示。提出了一个新颖的评估框架RealisticF…

VulnHub:insomnia

靶机下载地址 信息收集 主机发现和端口扫描 攻击机网段192.168.31.0/24。 # 主机发现 nmap 192.168.31.0/24 -Pn -T4 # 靶机ip:192.168.31.207 端口扫描 nmap 192.168.31.207 -A -p- -T4 经过nmap扫描发现目标主机有http服务&#xff0c;端口是8080。 目录扫描 访问http…

Android RSA 加解密

文章目录 一、RSA简介二、RSA 原理介绍三、RSA 秘钥对生成1. 密钥对生成2. 获取公钥3. 获取私钥 四、PublicKey 和PrivateKey 的保存1. 获取公钥十六进制字符串1. 获取私钥十六进制字符串 五、PublicKey 和 PrivateKey 加载1. 加载公钥2. 加载私钥 六、 RSA加解密1. RSA 支持三…

YOLOv2小白精讲

YOLOv2是一个集成了分类和检测任务的神经网络&#xff0c;它将目标检测和分类任务统一在一个单一的网络中进行处理。 本文在yolov1的基础上&#xff0c;对yolov2的网络结构和改进部分进行讲解。yolov1的知识点可以看我另外一篇博客&#xff08;yolov1基础精讲-CSDN博客&#xf…

MySQL的索引、事务

MySQL的索引 索引的概念 索引是一个排序的列表&#xff0c;在列表当中存储索引的值以及索引值对应数据所在的物理行。 索引值和数据是一一映射的关系。 索引的作用 使用索引之后就不需要扫描全表来定位某行的数据 加快数据库查询的速度。 索引可以是表中的一列也可以是多…