SpringCloud学习(七)——统一网关Gateway

news2024/11/14 20:20:11

文章目录

  • 1. 网关介绍
  • 2. 网关搭建
    • 2.1 引入依赖
    • 2.2 创建启动类
    • 2.3 编写配置
    • 2.4 测试
  • 3. 路由断言工厂
  • 4. 路由过滤器
    • 4.1 过滤器配置
    • 4.2 全局过滤器
    • 4.3 过滤器执行顺序
  • 5. 跨域问题处理

1. 网关介绍

到现在,我们可以使用Nacos对不同的微服务进行注册并管理配置文件,也可以使用 Feign 对不同的微服务进行访问,但是,这种访问是任何人都可以访问的,这是不行的,访问之间应该有某种权限的控制,而且,如果所有允许的访问都可以进入,那么如果有一个时间访问量太过巨大则会引起服务器出现问题,这就需要使得请求限流了,所以,我们需要使用一些工具来达到这些目的,这就是网关Gateway。
在这里插入图片描述
网关具体需要实现的功能包括:

  1. 对用户请求做身份认证、权限校验
  2. 将用户请求路由到微服务,并实现负载均衡
  3. 对用户请求做限流

SpringCloud中网关的实现有两种:

  • gateway
  • zuul

zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway则是基于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能,所以我们接下来使用Gateway来对网关进行实现。

2. 网关搭建

接下来我们就试着为userserviceorderservice 搭建网关。

2.1 引入依赖

首先初始化一个新的Module,将其初始化为空的Maven,统一网关实际上也是一个微服务,所以也需要在Nacos上进行注册发现,故添加如下依赖:

<dependencies>
    <!--    nacos服务发现注册依赖    -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <!--    网关gateway依赖    -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
</dependencies>

2.2 创建启动类

创建一个 GatewayApplication 的文件,将其当做启动类,该文件的内容如下:

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

2.3 编写配置

在网关这里,需要在 application.yml 配置中编写路由配置以及nacos的地址等配置信息,配置文件中的配置信息如下所示:

server:
  port: 10010
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由标示,必须唯一
          uri: lb://userservice # 路由的目标地址,lb是负载均衡,后面跟服务名称
          predicates: # 路由断言,判断请求是否符合规则
            - Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合
        - id: order-service
          uri: lb://orderservice
          predicates:
            - Path=/order/**

从配置信息可以看到,网关实现了负载均衡以及路径的断言,让访问变得更加的轻松方便。

2.4 测试

接下来我们将 userservice, orderservice, gateway 三个服务都启动,然后输入网址 http://localhost:10010/user/1 可以看到用户信息能够顺利显示出来。
在这里插入图片描述
再输入网址 http://localhost:10010/order/101 ,能够正确的显示相关的信息,
在这里插入图片描述
这说明我们的网关构建时成功的。

3. 路由断言工厂

我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理
转变为路由判断的条件。

例如 Path=/user/** 是按照路径匹配,这个规则是由 org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory 类来处理的,像这样的断言工厂在SpringCloudGateway中还有十几个。

Spring提供了11中基本的路由断言工厂,11中工厂如下,

名称说明
After只处理某个时间点后的请求
Before只处理某个时间点之前的请求
Between只处理某两个时间点之前的请求
Cookie请求必须包含某些cookie才处理
Header请求必须包含某些header才处理
Host请求必须是访问某个host(域名)才处理
Method请求方式必须是指定方式才处理
Path请求路径必须符合指定规则才处理
Query请求参数必须包含指定参数才处理
RemoteAddr请求者的ip必须是指定范围才处理
Weight权重处理

所有这些断言工厂的实例都可以在Spring官网中找到。

比如我们需要只处理上海市2024年3月28日的orderservice请求,那么修改配置文件如下:

server:
  port: 10010
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由标示,必须唯一
          uri: lb://userservice # 路由的目标地址,lb是负载均衡,后面跟服务名称
          predicates: # 路由断言,判断请求是否符合规则
            - Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合
        - id: order-service
          uri: lb://orderservice
          predicates:
            - Path=/order/**
            - After=2024-03-28T17:42:47.789-07:00[Asia/Shanghai]

上面仅新增了最后一行,这样,因为现在是2023年,所以访问 http://localhost:10010/order/101 必定会失效。

4. 路由过滤器

Gateway不可能所有请求都进行响应,其会根据一些条件,将不符合的路径进行过滤,这也就是路由过滤器GatewayFilter的作用,对进行网关的请求和微服务返回的响应做出处理。
在这里插入图片描述

4.1 过滤器配置

Spring中提供了30+种不同的路由过滤器工厂,这里就不一一列举出来了,所有的路由过滤器工厂都能在Spring官网进行查看。

比如这里,可以使用过滤器给userservice 添加一个请求头,添加如下:

server:
  port: 10010
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由标示,必须唯一
          uri: lb://userservice # 路由的目标地址,lb是负载均衡,后面跟服务名称
          predicates: # 路由断言,判断请求是否符合规则
            - Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合
		  filters:
		    - AddRequestHeader=Truth,I am a really ikun!

则上面的代码会对所有的 userservice 服务添加一个请求头。

如果想要对所有的请求都添加一个请求头应该怎么做呢?
只需要定义 default-filters 即可,定义的过滤器如下:

server:
  port: 10010
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由标示,必须唯一
          uri: lb://userservice # 路由的目标地址,lb是负载均衡,后面跟服务名称
          predicates: # 路由断言,判断请求是否符合规则
            - Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合
	  default-filters:
		- AddRequestHeader=Truth,I am a really ikun!

4.2 全局过滤器

全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与 default-filters 的作用一样区别在于 default-filters 通过配置定义,处理逻辑是固定的。而 GlobalFilter 的逻辑需要自己
写代码实现。

全局过滤器的实现步骤如下:

  • 实现 GlobalFilter 接口
  • 添加 @Order 注解或实现 Ordered 接口,目的是设置过滤的优先级
  • 编写处理逻辑

比如我们定义一个全局过滤器,拦截请求,判断请求的参数是或符合下面的条件:

  • 参数中是否有 authorization
  • authorization 参数值是否为 admin

如果同时满足,则对请求进行放行。

我们在 gateway 的Module中创新一个 AuthorizeFilter 的全局过滤文件,其文件内容如下;

// @Order 注解定义过滤器优先级,值越小,优先级越高,也可以通过Ordered接口实现
@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1.获取请求参数
        ServerHttpRequest request = exchange.getRequest();
        MultiValueMap<String, String> params = request.getQueryParams();
        // 2.获取参数中的 authorization 参数
        String auth = params.getFirst("authorization");
        // 3.判断参数值是否等于 admin
        if ("admin".equals(auth)) {
            // 4.是,放行
            return chain.filter(exchange);
        }
        // 5.否,拦截
        // 5.1.设置状态码
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        // 5.2.拦截请求
        return exchange.getResponse().setComplete();
    }
}

之后再使用 http://localhost:10010/order/101 ,则网页会报告我们所设置的状态码的错误,错误如下:
在这里插入图片描述
而如果使用 http://localhost:10010/order/101?authorization=admin , 则网页能够正常访问。

4.3 过滤器执行顺序

请求进入网关会碰到三类过滤器:当前路由的过滤器、DefaultFilter、GlobalFilter
请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器,那么过滤器链的执行顺序是怎样的呢?

过滤器执行顺序如下:

  • 每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前。
  • GlobalFilter 通过实现 Ordered 接口,或者添加 @Order 注解来指定 order 值,由我们自己指定
  • 路由过滤器和 defaultFilterorder 由Spring指定,默认是按照声明顺序从1递增。即如果定义了多个过滤器配置,则其第一行优先级是1,第二行优先级是2,以此类推
  • 当过滤器的 order 值一样时,会按照 defaultFilter > 路由过滤器 > GlobalFilter 的顺序执行。

5. 跨域问题处理

跨域问题指的是不同站点之间,使用 ajax 无法相互调用的问题。跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据,但这个保护机制也带来了新的问题,它的问题是给不同站点之间的正常调用,也带来的阻碍。简单来说就是浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题。

在请求时,如果出现了以下情况中的任意一种,那么它就是跨域请求:

  • 协议不同,如 httphttps
  • 域名不同;
  • 端口不同。

也就是说,即使域名相同,如果一个使用的是 http,另一个使用的是 https,那么它们也属于跨域访问。常见的跨域问题如下图所示:

当前页面被请求页面是否跨域
http://www.test.com/http://www.test.com/index.html
http://www.test.com/https://www.test.com/index.html是,协议名不同(http,https)
http://www.test.com/http://www.baidu.com/是,主域名不同(test,baidu)
http://www.test.com/http://blog.test.com/是,子域名不同(www,blog)
http://www.test.com:8080/http://www.test.com:8081/是,端口不同(8080,8081)

而解决跨域问题的方案就是 CORSCORS 是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing),允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。它通过服务器增加一个特殊的Header[Access-Control-Allow-Origin]来告诉客户端跨域的限制,如果浏览器支持CORS、并且判断Origin通过的话,就会允许XMLHttpRequest发起跨域请求。

网关处理跨域问题采用的方案同样是CORS方案,且只需要经行简单的配置即可,配置如下:

spring:
  cloud:
    gateway:
      globalcors: # 全局的跨域处理
        add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
        cors-configurations:
          '[/**]': # 对哪些网址进行配置,[/**] 指的是所有网址
            allowedOrigins: # 允许哪些网站的跨域请求
              - "http://localhost:8090"
              - "http://www.leyou.com"
            allowedMethods: # 允许的跨域AJAX请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允许在请求头中携带的头信息
            allowedCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期,有效期内无需再次检查请求

按照这种格式进行配置即可解决跨域问题。

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

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

相关文章

淘宝天猫公布618整体活动节奏

5月4日消息&#xff0c;淘宝直播618选品会近日在杭州成功举办&#xff0c;淘宝直播商品中心团队和天猫、全球购行业小二在会上与商家、达人主播等参会人士探讨如何选品才能打动消费者、如何保障货品的质量安全、如何完善商品的售后服务等问题&#xff0c;共同分析直播电商行业中…

verilog驱动LCD显示彩条、字符

verilog驱动LCD显示彩条、字符 一、简介 LCD&#xff08;liquid crystal display&#xff09;:液晶显示器 TFT&#xff1a;薄膜晶体管 LCD屏幕接口&#xff1a;常见的LCD屏幕接口有&#xff1a;RGB、MCU、LVDS、MIPI等 RGB LCD接口原理图&#xff1a;其中MISO、MOSI是IIC接…

Acjudge #P1004. 整除三元组

蒟蒻来讲题&#xff0c;还望大家喜。若哪有问题&#xff0c;大家尽可提&#xff01; Hello, 大家好哇&#xff01;本初中生蒟蒻讲解一下Acjudge #P1004. 整除三元组! 原题 题目背景 潍坊高新OI社区打算开讲“数论”了&#xff0c;大家赶紧来学习一下“整除”吧。 题目描述 …

第一章 数字图像本质及基础操作

系列文章目录 第一章 图像本质及基础操作 文章目录 系列文章目录前言一、数字图像的本质二、图像基础理论1.色彩空间1.1 RGB模型1.2 HSV模型1.3 HSL模型1.4 YUV模型1.5 灰度图1.6 OpenCV中色彩空间转换 2.图片的存储3.图像参数 三、图像的基础操作及OpenCV画图1.图像的基础操作…

Hololens2开发指南

练习 - 导入和配置资源 - Training | Microsoft Learn unity需要高版本 用2019.4.30支持平台这没有openxr 用2020.3.36可以&#xff0c;2021版本也可以出现

代码随想录算法训练营第三十天 | 航班问题、二维回溯

回溯法小结 本周小结&#xff01;&#xff08;回溯算法系列三&#xff09; | 代码随想录 (programmercarl.com) 性能分析 子集问题分析&#xff1a; 时间复杂度&#xff1a;O(n 2n)&#xff0c;因为每一个元素的状态无外乎取与不取&#xff0c;所以时间复杂度为O(2n)&…

蚁群算法-车辆配载率的路径优化

车辆配送路径优化问题可描述为&#xff1a;某商超配送中心要使用一定数量的车辆对一批货物进行配送服务&#xff0c;要求在不超过车辆的额定载重量和额定容积的条件下&#xff0c;安排这些货物的装载&#xff0c;使得车辆利用率最高。 针对以上问题做出假设&#xff1a; (1) 只…

Python学习笔记(1)

《Python编程&#xff1a;从入门到实践》学习笔记 python编程软件PyCharm Community Edition 2022.3.2&#xff0c;快捷键&#xff1a;Ctrl/ 表示注释Python代码。 一、变量的命名和使用 1.变量名只能包含字母、数字和下划线。变量名可以字母或下划线打头&#xff0c;但不能以数…

Java开发初学者实用网站

1.慕课网&#xff08;http://www.imooc.com&#xff09;&#xff1a;提供了大量的Java在线教程和视频。 优点 1.广泛的开放性&#xff1a;大规模、开放性和受众广 2.透明性&#xff1a;根据不同兴趣、准备情况和时间来学习所需课程 3.优质资源易获取性&#xff1a;让每位学生…

Python每日一练(20230504)

目录 1. 课程表 Course Schedule I 2. 课程表 Course Schedule II &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 课程表 Course Schedule I 你这个学期必须选修 numCourses 门课程&a…

linux ll命令是什么

ll并不是linux下一个基本的命令&#xff0c;它实际上是ls -l的一个别名。 # 查看指定目录下的内容&#xff0c;默认查看当前目录下内容 ls [-ald] [目录名] # 目录名不填写&#xff0c;默认为当前目录。 # -a&#xff1a;列出的全部的文件&#xff0c;包括隐藏文件 # -l&#x…

医院PACS系统源码,各种类型图像专业的图像处理功能,海量数据存储与检索

RIS/PACS系统源码 RIS/PACS系统源码在预约登记、分诊叫号、技师检查、诊断报告、临床浏览、科室管理等环节满足全院相关科室的要求。在医学影像下载、浏览、处理中满足速度快、强化常用功能、方便阅片等要求。满足放射、超声、内镜、病理等影像科室的业务需求。通过与HIS、LIS…

阿里云AMD服务器CPU:AMD EPYC Genoa 9T34处理器性能

阿里云AMD服务器AMD EPYC Genoa 9T34处理器&#xff0c;主频3.4 GHz&#xff0c;单核睿频最高3.75 GHz&#xff0c;计算性能稳定&#xff0c;阿里云百科分享AMD EPYC™ Genoa 9T34性能测评&#xff1a; 目录 AMD EPYC™ Genoa 9T34 AMD EPYC™ Genoa 9T34 阿里云AMD服务器性…

基于YOLOv4的目标检测系统(附MATLAB代码+GUI实现)

摘要&#xff1a;本文介绍了一种MATLAB实现的目标检测系统代码&#xff0c;采用 YOLOv4 检测网络作为核心模型&#xff0c;用于训练和检测各种任务下的目标&#xff0c;并在GUI界面中对各种目标检测结果可视化。文章详细介绍了YOLOv4的实现过程&#xff0c;包括算法原理、MATLA…

Windows中批量修改DNS记录

最近由于公网映射的IP需要更换&#xff0c;有一批DNS记录需要修改。对于使用Windows管理的DNS记录&#xff0c;可以使用Powershell批量导出记录更新后再批量修改。 首先使用Powershell将DNS服务器上test.local这个区域里的所有A记录导出 Get-DnsServerResourceRecord -Comput…

计算机专业大一的一些学习规划建议!

大家好&#xff0c;我是小北。 五一嗖的一下就过啦~ 对于还在上学的同学五一一过基本上意味着这学期过半了&#xff0c;很多大一、大二的同学会有专业分流、转专业等事情。 尤其是大二的时候&#xff0c;你会发现身边有些同学都加入各种实验室了&#xff0c;有忙着打ACM、学生…

初级算法-贪心算法

主要记录算法和数据结构学习笔记&#xff0c;新的一年更上一层楼&#xff01; 初级算法-贪心算法 一、分发饼干二、摆动序列三、最大子序和四、买卖股票最佳时机五、跳跃游戏六、跳跃游戏二七、k次取反后最大化的数组和八、加油站九、分发糖果十、柠檬水找零十一、根据身高重建…

Python实现哈里斯鹰优化算法(HHO)优化随机森林分类模型(RandomForestClassifier算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 2019年Heidari等人提出哈里斯鹰优化算法(Harris Hawk Optimization, HHO)&#xff0c;该算法有较强的全…

SPSS如何检验非参数之案例实训?

文章目录 0.引言1.卡方检验2.二项检验3.双独立样本检验4.多独立样本检验5.双配对样本检验6.多配对样本检验7.游程检验8.单样本K-S检验 0.引言 因科研等多场景需要进行绘图处理&#xff0c;笔者对SPSS进行了学习&#xff0c;本文通过《SPSS统计分析从入门到精通》及其配套素材结…

文献集锦 | 非因空间多组学技术在胰腺癌肿瘤微环境中的研究策略

胰腺导管腺癌(PDAC)仍然是一种难治性疾病&#xff0c;5年总生存率&#xff08;OS&#xff09;仅不到9%&#xff0c;且诊断时多为晚期&#xff0c;治疗手段有限&#xff0c;除了传统的手术切除、放化疗之外&#xff0c;目前越来越多采用新辅助治疗的方法。利用空间组学分析平台深…