Spring Cloud Gateway 的简单介绍和基本使用

news2024/11/26 14:28:36

前言

本文主要对Spring Cloud Gateway进行简单的概念介绍,并通过多模块编程的方式进行一个简单的实操。

文章目录

  • 前言
  • 1 什么是网关(概念)
  • 2 微服务中的网关
    • 2.1 问题1
    • 2.2 问题2
  • 3 网关作用
  • 4 Spring Cloud Gateway组成
  • 5 Spring Cloud Gateway基础使用
    • 5.1 父类pom.xml依赖
    • 5.2子模块Userservice
    • 5.3 子模块GatewayService
    • 5.4 实操1
    • 5.5 实操2
    • 5.6 注意事项
  • 6 断言类型

1 什么是网关(概念)

网关是一种网络设备,它用于连接不同网络之间的数据传输。它是在网络层级上工作的,能够将数据从一个网络传输到另一个网络。网关可以是物理设备,如路由器,也可以是软件程序,如网络服务器

2 微服务中的网关

在微服务架构中,网关的作用主要是用来作为客户端内部服务端之间中间转发人,因为在微服务架构中,后端服务基本上会被放在私网中,不对外开放地址的,那么客户端身在远方不跟后端服务在一个私网中,是无法通过具体地址访问到后端服务的。

那么这个时候,就需要一个中间人作为连接二者的点,而这个中间人,在私网中,唯独他的IP对外开放,服务器多的情况下,这个中间人还需要额外做一份请求分发的工作,这个中间人我们专业一点就叫做:网关

2.1 问题1

在这里插入图片描述 问:这个时候可能会有朋友会问:客户端和服务端沟通不是可以通过OpenFeign+LoadBalancer吗????

在这里插入图片描述 答:现在的项目前后端分离项目比较多,我们后端是Java,OpenFeign+LoadBalancer的使用需要Jar包,但是我们前端(Vue、三剑客)语言并不能适配Jar包,所以就需要第三个人作为中间人,衔接前端客户端和后端服务端,而OpenFeign+LoadBalancer则作为后端中的通信使用,或者你可以理解访问过程为:前端客户端->网关->后端客户端->后端服务端
在这里插入图片描述

2.2 问题2

在这里插入图片描述 问:为什么不用Nginx这种反向代理作为中间人?

在这里插入图片描述 答:在微服务架构中,你要部署很多个后端且独立存在,这就意味着我前脚在这台服务器上刚登录认证过,后脚我的请求到另一台服务器就被认为是未认证请求,这不就成了我的每一次请求都被提示未登录认证。而我们的网关可以统一认证处理,就实现一次登录,各服务端生效的效果,当然还不止这些效果,接下来便会逐一介绍。

3 网关作用

  • 路由功能:网关可以根据目标地址不同,选择最佳路径将请求从源地址发送到目标地址。
  • 安全控制(统一鉴权):网关可以设置安全策略,对数据包进行检查和过滤,可以验证和授权网络数据包,并阻止未授权数据包访问。(防火墙是一种常用的网关设备,用于保护和过滤网络免收恶意攻击和未经授权的访问)
  • 协议转换:不同网络使用不同的通信协议,网关可以进行协议转换,使不同设备之间可以互相访问(例如:HTTP->HTTPS)
  • 网络地址转换(NAT):网络地址转换,将内部私有IP地址转换为外部网络公共IP地址。

总而言之,网关是一个关键的网络设备,它起到连接不同网络之间的桥梁作用,使得数据能够在不同网络之间传输和交换。

4 Spring Cloud Gateway组成

  • 路由(route):定义了请求应该被发往到哪个的服务端的目标地址,路由由路由ID、断言、目标URI、过滤器组成。通过配置多个路由器,可以实现不同请求的路由规则。
  • 断言(Predicate):用于匹配请求的条件,请求匹配断言条件,则会被路由到对应的目标地址。断言可以基于请求的路径、请求头、请求参数等信息进行匹配。
  • 过滤器(Filter):用于路由请求前后统一处理,如添加请求头、修改请求体等。

5 Spring Cloud Gateway基础使用

下面我们通过多模块编程的方式演示Spring Cloud Gateway的使用,跳过创建过程,直接展示结果:
在这里插入图片描述

5.1 父类pom.xml依赖

<?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>
    <groupId>com.example</groupId>
    <artifactId>Spring-Cloud-Gateway-Demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Spring-Cloud-Gateway-Demo</name>
    <description>Spring-Cloud-Gateway-Demo</description>
    <packaging>pom</packaging>
    <modules>
        <module>UserService</module>
        <module>GatewayService</module>
    </modules>
    <properties>
        <java.version>17</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>3.0.2</spring-boot.version>
        <spring-cloud.version>2022.0.0</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

5.2子模块Userservice

<?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>
    <groupId>com.example</groupId>
    <artifactId>UserService</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>UserService</name>
    <description>UserService</description>
    <parent>
        <groupId>com.example</groupId>
        <artifactId>Spring-Cloud-Gateway-Demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.example.userservice.UserServiceApplication</mainClass>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

application.yml

server:
  port: 10086

controller代码

@RestController
@RequestMapping("/user")
public class UserControler {

    @RequestMapping("/getrandom")
    public String getRandom(){
        return "userservice:10086-"+new Random().nextInt(1000);
    }
}

5.3 子模块GatewayService

Spring Cloud Gateway分为两个步骤:

  1. 导入Gateway依赖(pom文件)
  2. 设置网关规则(yml文件)
<?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>
    <groupId>com.example</groupId>
    <artifactId>GatewayService</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>GatewayService</name>
    <description>GatewayService</description>
    <parent>
        <groupId>com.example</groupId>
        <artifactId>Spring-Cloud-Gateway-Demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.example.gatewayservice.GatewayServiceApplication</mainClass>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

</project>

application.yml

server:
  port: 8080

spring:
  cloud:
    gateway:
      routes:
      - id: userservice #服务ID
        uri: http://localhost:10086 #目的地址路由
        predicates: #断言
          - Path=/user/** #断言匹配规则

5.4 实操1

启动UserService和启动GatewayService
在这里插入图片描述
我们先正常访问UserService中的路由(http://localhost:10086/user/getrandom)
结果:
在这里插入图片描述

现在已经确认UserService是正常的,那么我们接下来就看看通过网关(http://localhost:8080/user/getrandom)能不能访问到它:

在这里插入图片描述
从中可以发现,我们的Gateway可以帮我们去完成请求转发到适合的服务端上。

5.5 实操2

如果是对于多组的路由该如何编写GatewayService的application.yml呢?编写时又该注意什么?
以下面为例进行说明:
在这里插入图片描述

server:
  port: 8080

spring:
  cloud:
    gateway:
      routes:
      - id: userservice
        uri: http://localhost:10086 #路由
        predicates:
          - Path=/user/**, /update/**
      - id: adminservice
        uri: http://localhost:9000
        predicates:
          - Path=/admin/**

照虎画猫,我们在创建adminservice子模块与/update/xxx服务

UpdateController类
在这里插入图片描述

@RestController
@RequestMapping("/update")
public class UpdateController {

    @RequestMapping("/op")
    public String updateOrInsert(){
        return "updateOrInsert";
    }
}

AdminService.AdminController
在这里插入图片描述

@RestController
@RequestMapping("/admin")
public class AdminController {

    @RequestMapping("/getroles")
    public String getRoles(){
        return "AdminService:9000-admin";
    }
}

下面就进行访问测试,网关能否正确应对多个请求的分发
http://localhost:8080/update/op (√)
在这里插入图片描述
http://localhost:8080/admin/getroles(√)
在这里插入图片描述

补充:
上面我们介绍了application.yml文件中对于数组的写法,而对于application.propeties编写方式如下

server.port=9000
spring.cloud.gateway.routes[0].id=userservice
spring.cloud.gateway.routes[0].uri=http://localhost:10086
spring.cloud.gateway.routes[0].predicates[0]=Path=/user/**
spring.cloud.gateway.routes[0].predicates[1]=Path=/update/**
spring.cloud.gateway.routes[1].id=adminservice
spring.cloud.gateway.routes[1].uri=http://localhost:9000
spring.cloud.gateway.routes[1].predicates[0]=Path=/admin/**

5.6 注意事项

细心的朋友可能已经发现了,在多模块项目中,我的SpringWeb依赖没有放到父模块pom中,而是放在子模块。

这是因为父类中添加SpringWeb依赖会导致全子类都使用,而我们的Spring Cloud Gateway是基于Reactive进行开发的,不能使用简单的Spring Web依赖,需要使用Spring Reactive Web依赖,但是Spring Cloud Gateway底层中已经包含了这个依赖,所以我们没有在GatewayService中导入Spring Reactive Web,在其他子模块中导入Spring web依赖的原因。
在这里插入图片描述
假如我们错误的将Spring Web适用到Spring Cloud Gateway模块中,也会有error抛出,示例如下:
在这里插入图片描述
错误中也告诉我们解决方式,要么在gateway中使用Spring Reactive Web要么吧Spring Web移除

6 断言类型

Spring Cloud Gateway支持的断言类型目前有12种,包含以下这些:

  1. 根据时间匹配(包含3中类型)
    a. After:请求在指定时间之后才匹配
    b. Before: 请求在指定时间之前才匹配
    c. Between: 请求在指定时间中才匹配
  2. cookie:配置请求中的Cookie值
  3. Header:配置请求中的Header值
  4. Host:匹配请求头中的Host值
  5. Method:匹配请求头中的Method的值
  6. Path: 匹配请求路径
  7. Query: 匹配请求参数
  8. RemoteAddr:匹配请求的IP地址,支持IPV4和IPV6
  9. Weight:根据权重来分发请求,权重根据Group来计算
    10.XForwardRemoteAddr:根据X-ForWord-For匹配

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

其中Cookie和Header方式的匹配需要配合正则表达式来使用

正则表达式

  1. \w+:匹配一个或多个字母、数字、下划线字符
  2. \s+:匹配一个或多个空白字符 (包括空格、制表符、换行符等)。
  3. .*:匹配任意字符(除了换行符) 零次或多次
  4. .+:匹配除了换行符之外的任意字符一次或多次。
  5. [abc]:匹配字符集中的任意一个字符,例如 [abc] 可以匹配a、b或c。
  6. [^abc]:匹配除了字符集中的任意字符之外的任意字符,例如[^abc] 可以匹配除了a、b和c之外的任意字符
  7. ^:匹配字符串的开始位置
  8. $:匹配字符串的结束位置
    9.|:表示"或”的意思,用于匹配多个模式中的任意一个10.(): 用10.():于分组,可以将一组字符作为一个整体进行匹配。
END
希望对你有所帮助

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

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

相关文章

51代码审计-PHP框架MVC类上传断点调试

知识点1&#xff0c;文件上传漏洞挖掘 搜索关键字$_FILES phpmvc架构 MVC模式&#xff08;Model-View-Controller&#xff09;是软件工程中的一种软件架构模式。 MVC把软件系统分为三个基本部分&#xff1a;模型&#xff08;Model&#xff09;、视图&#xff08;View&#…

5.前端--CSS-基本概念【2023.11.26】

1. CSS 语法规范 CSS 规则由两个主要的部分构成&#xff1a;选择器以及一条或多条声明。 属性和属性值之间用英文“:”分开 多个“键值对”之间用英文“;”进行区分 选择器 : 简单来说&#xff0c;就是选择标签用的。 声明 &#xff1a;就是改变样式 2.CSS引入方式 按照 CSS 样…

【C++】多线程(一):std::thread的使用

这篇文章应我朋友的邀请&#xff0c;写一篇文章介绍下C多线程。 编译环境准备 首先确定你的编译器支持std的thread&#xff0c;如果不支持&#xff0c;就会出现诸如“thread找不到”的问题。 以下假设你使用 gnu gcc 编译器&#xff0c;因为 MSVC 的我也不太熟悉。 linux …

【详解二叉树】

&#x1f320;作者&#xff1a;TheMythWS. &#x1f387;座右铭&#xff1a;不走心的努力都是在敷衍自己&#xff0c;让自己所做的选择&#xff0c;熠熠发光。 目录 树形结构 概念 树的示意图 树的基本术语 树的表示 树的应用 二叉树(重点) 二叉树的定义 二叉树的五…

实战oj题——用队列实现栈

前言&#xff1a;Leetcode栈和队列的习题&#xff0c;用两个队列实现栈。 【由于我们是用C语言完成这道题&#xff0c;所以我们要将关于队列的实现代码插入到题中&#xff0c;在创建一个栈&#xff0c;栈里包含两个队列。】 思路&#xff1a;我们用两个队列来实现&#xff0c;因…

java学习part12多态

99-面向对象(进阶)-面向对象的特征三&#xff1a;多态性_哔哩哔哩_bilibili 1.多态&#xff08;仅限方法&#xff09; 父类引用指向子类对象。 调用重写的方法&#xff0c;就会执行子类重写的方法。 编译看引用表面类型&#xff0c;执行看实际变量类型。 2.父子同名属性是否…

FPGA驱动CS4344 VHDL例程

CS4344是一款非常简单的I2S立体声24bit D/A芯片&#xff0c;采样率高达192KHz&#xff0c;相对于ADAU1761复杂的寄存器配置来说&#xff0c;CS4344非常友好&#xff0c;无需配置寄存器&#xff0c;只要按I2S时序输入数据&#xff0c;即可实现立体声输出&#xff0c;且10PIN TSS…

Effective Modern C++(1.顶层const与底层const)

1.顶层const与底层const的定义 const修饰的变量不可以改变&#xff0c;那么他就是顶层const&#xff0c;如&#xff1a; const int a 10; 那么&#xff0c;对于 const int *const p new int(10); 第二个const就是顶层const&#xff0c;因为他修饰的是p&#xff1b;第一个…

Windows TCP 通信测试_1

一、单对单通信测试 应用函数 socket、bind、connect、listen、accept、recv、send&#xff08;win下的函数&#xff09;等 1、客户端demo client.cpp #include<WINSOCK2.H> #include<STDIO.H> #include<iostream> #include<cstring> using namespa…

电商项目高级篇-03 商品上架

商品上架 1、商品上架1.1、设计&#xff1a;宽表设计 1、商品上架 上架的商品才可以在网站展示。 上架的商品需要可以被检索。 1.1、设计&#xff1a;宽表设计 优点&#xff1a;方便检索 缺点&#xff1a;数据冗余 商品数据模型设计&#xff1a; PUT product {"mappi…

HarmonyOS开发(七):构建丰富页面

1、组件状态管理 1.1、概述 在应用中&#xff0c;界面一般都是动态的。界面会根据不同状态展示不一样的效果。 ArkUI作为一种声明式UI&#xff0c;具有状态驱动UI更新的特点&#xff0c;当用户进行界面交互或有外部事件引起状态改变时&#xff0c;状态的变会会触发组件的自动…

【企业微信连接问题】

1、个人可以创建企业微信的企业账号么&#xff1f; 答&#xff1a;可以的&#xff0c;只是没法认证。不过基础的功能还是有的。 注册步骤&#xff1a;企业微信注册步骤 2、集简云链接企业微信&#xff0c;在授权之后&#xff0c;找不到集简云怎么办&#xff1f; 答&#xff1a…

美化wordpress复制文章内容弹出版权提示框的源码代码

通过SweetAlert美化的提示框 将下面代码添加到当前主题模板函数functions.php文件最后即可&#xff1a; function zm_copyright_tips() { echo <link rel"stylesheet" type"text/css" rel"external nofollow" target"_blank" href…

人力资源管理后台 === 权限应用

目录 1.权限应用-拆分静态路由-动态路由 2.权限应用-根据用户权限添加动态路由 3.权限应用-根据权限显示左侧菜单 4.权限应用-退出登录重置路由 5.权限应用-功能权限-按钮权限标识 6.权限应用-自定义指令应用功能权限 7.其他模块-集成 8.首页-基本结构和数字滚动 9.首页…

编译器设计03-后端概述

后端处理概述 后端处理&#xff1a;中间代码生成&#xff0c;目标代码生成&#xff0c;贯穿各个阶段的优化。 后端处理犹如得出中文文章&#xff0c;当阅读完英语文章后&#xff0c;你的脑海中就有清晰的“中间代码”了&#xff0c;想写作的时候就心中有数&#xff0c;核心论…

Sringboot3 讲解

文章目录 前言一、Springboot快速入门1.1 实例1.2 总结&#xff1a;1.2.1 什么是starter启动器1.2.2 SpringBootApplication注解的功效 二、springboot3 统一配置文件1.概述2、属性配置文件使用简单案例3、yaml配置介绍和说明4、批量配置文件的读取5、多环境配置和激活 三、spr…

vue页面表单提交时如何做校验

我们在做新增的时候&#xff0c;新增对话框是要加必填校验的&#xff0c;否则就可能会加空数据或者会产生sql的报错。那么这个校验是如何加的呢&#xff1f;下面我们来说一下。 文章目录 一、必填校验1.1 给form表单绑定一个:rules校验规则&#xff0c;给每个item加上一个prop…

17.找出1000之内的所有完数。

文章目录 前言一、题目描述 二、题目分析 三、解题 程序运行代码 前言 本系列为循环结构编程题&#xff0c;点滴成长&#xff0c;一起逆袭。 一、题目描述 一个数如果恰好等于它的因子之和&#xff0c;这个数就称为“完数”。例如&#xff0c;⑥的因子为1、2、3&#xff0c;而…

创建可以离线打包开发的uniapp H5项目

安装node环境 略 安装vue脚手架&#xff0c;在线 npm install -g vue/cli PS&#xff1a;vue-cli已进入维护模式&#xff0c;vue3最新脚手架使用npm init vuelatest安装&#xff0c;安装后使用create-vue替换vue指令&#xff0c;create-vue底层使用vite提升前端开发效率&…

【c++文件】

C是一种面向对象的编程语言&#xff0c;它广泛应用于各个领域&#xff0c;如游戏开发、嵌入式系统、操作系统等。在C编程中&#xff0c;文件操作是一项非常重要的技能。本文将介绍C文件操作的基本知识以及一些有趣的应用&#xff0c;带领大家一起探索C文件操作的魅力。 一、C文…