Spring Cloud之Gateway网关学习【详细】

news2025/2/25 5:21:14

目录

统一网关Gateway

网关的实现

搭建网关

编写配置文件

路由断言工程

路由的过滤器

全局过滤器

网关过滤器执行顺序

网关的cors跨域配置

问题及解决


统一网关Gateway

网关的实现

SpringCloud中存在两种网关

  1. gateway:基于Spring5中提供的WebFlux实现,属于响应式编程,性能更好
  2. zuul:基于Servlet实现,阻塞式编程

搭建网关

首先网关也属于微服务的一个模块,也需要注册到Nacos与拉去Nacos的信息,创建gateway模块并引入以下两个依赖。

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

Gateway也是一个服务,需要一个启动类

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

编写配置文件

server:
  port: 10010
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos的地址
    gateway:
      routes: # 路由地址
        - id: user-server # 路由唯一标识(自定义,只要唯一)
          uri: lb://user-server #路由目标地址
          predicates: # 路由断言。判断请求是否符合规则
            - Path=/user/**
        - id: order-service # 路由唯一标识
          uri: lb://order-service #路由目标地址
          predicates: # 路由断言。判断请求是否符合规则
            - Path=/order/**

启动网关服务,访问网关地址观察结果

具体流程如下

路由断言工程

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

例如Path=从user/**是按照路径匹配,这个规则是由org.springframework.cloud.gateway.handlerpredicate.PathRoutePredicateFactory类来处理的。

Spring提供了11种基本的Predicate工厂

名称

说明

示例

After

是某个时间点后的请求

-After=2037-01-20T17:42:47.789-07:00[America/Denver]

Before

是某个时间点前的请求

-Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]

Between

是某两个时间点之前的请求

-Between=2037-01-20T17:42:47.789-07:00[America/Denver],2037-01-21T17:42:47.789-07:00[America/Denver]

Cookie

请求必须包含某些cookie

- Cookie=chocolate, ch.p

Header

请求必须包含某些header

-Header=X-Request-ld,\d+

Host

请求必须是访问某个host (域名)

-Host=**.somehost.org,**.anotherhost.org

Method

请求方式必须是指定方式

-Method=GET,POST

Path

请求路径必须符合指定规则

-Path=/red/{segment),/blue/**

Query

请求参数必须包含指定参数

-Query=name,Jack或者- Query=name

RemoteAddr

请求者的ip必须是指定范围

-RemoteAddr=192.168.1.1/24

Weight

权重处理

路由的过滤器

Spring提供了31种不同的路由过滤器工厂,具体可以去看SpringCloud文档,下面案例实现一个最基本的添加请求头过滤器。我们向/order所有请求添加一个gateway=hello world的请求头

首先添加配置

spring:
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos的地址
    gateway:
      routes: # 路由地址
        - id: order-service # 路由唯一标识
          uri: lb://order-service #路由目标地址
          predicates: # 路由断言。判断请求是否符合规则
            - Path=/order/**
          filters:
            - AddRequestHeader=gateway,hello world

在OrderController中添加参数,并打印

@GetMapping("{orderId}")
public Order queryOrderByUserId(@PathVariable("orderId") Long orderId,@RequestHeader(value = "gateway",required = false) String str) {
    System.out.println("---------"+str);
    // 根据id查询订单并返回
    return orderService.queryOrderById(orderId);
}

访问观察控制台输出。

成功打印信息。

刚刚是针对某个路由生效,如果想要每个路由都生效,应该选择默认过滤器配置

spring:
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos的地址
    gateway:
      routes: # 路由地址
        - id: order-service # 路由唯一标识
          uri: lb://order-service #路由目标地址
          predicates: # 路由断言。判断请求是否符合规则
            - Path=/order/**
      default-filters:
        - AddRequestHeader=gateway,hello world

全局过滤器

与Gateway的默认过滤器一样,处理一切进入网关请求和微服务响应。区别在于GatewayFilter通过配置定义,处理逻辑固定,而全局过滤器可以自己实现处理逻辑,实现方式就是实现GlobalFilter接口。下面写一个简单的登录拦截功能

/**
 * 登录认证过滤器
 */
@Order(-1)
@Component
public class authorizeFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //第一步获取请求参数
        ServerHttpRequest request = exchange.getRequest();
        MultiValueMap<String, String> params = request.getQueryParams();
        //获取参数中的authorize参数
        String authorize = params.getFirst("authorize");
        //判断参数是否等于admin
        if (authorize.equals("admin")){
            //等于,放行
            return chain.filter(exchange);
        }
        //设置状态码
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        return exchange.getResponse().setComplete();
    }
}

启动,并不添加验证访问测试

添加验证参数再次访问

网关过滤器执行顺序

请求进入网关会碰到3种过滤器:当前路由过滤器、DefaultFilter、GlobalFilter。

请求路由后,会将这三种过滤器合并到一个过滤器链(集合)中,排序后依次执行每个过滤器

首先比较order值,越小越先执行。GlobalFilter的order由我们指定,其他两种过滤器如果没有指定则由Spring指定order值,默认根据声明顺序来从1递增,当order值相同时,会按照defaultFilter>路由过滤器>GlobalFilter的顺序执行。

网关的cors跨域配置

跨域:是指域名不同。比如说:

  • 域名不同: www.taobao.com 和 www.taobao.org 与 www.jd.com 和 miaosha.jd.com
  • 域名相同,端口不同: localhost:8080和localhost:8081

跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题。

解决跨域问题:配置如下信息

spring:
  cloud:
    gateway:
      globalcors:
        add-to-simple-url-handler-mapping: true #一定要配置,主要解决options请求被拦截问题
        cors-configurations:
          '[/**]': #拦截路径
            allowedOrigins: #允许哪些网站跨域请求
              - "http://localhost:5500"
              - "http://www.域名.com"
            allowedMethods: #允许的跨域ajax请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" #允许在请求中携带的头信息
            allowCredentials: true #是否允许携带Cookie
            maxAge: 360000 #本次跨域检测的有效期

编写一个简单的html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>测试</title>
</head>
<body>
</body>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
    axios.get("http://localhost:10010/user/1?authorize=admin")
    .then(res=> console.log(res.data))
    .catch(err=>console.log(err))
</script>
</html>

使用VSCode启动该页面

问题及解决

如果出现此类错误

说明该请求没有被放行,可以尝试将配置文件中的localhost修改成127.0.0.1。或者修改C:\Windows\System32\drivers\etc\hosts文件添加如下信息即可

127.0.0.1 localhost

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

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

相关文章

[AUTOSAR][诊断管理][ECU][$28] 通信控制

文章目录 一、简介二、 应用场景三、通信控制基本原理四、服务请求请求格式请求实例服务响应正响应格式负响应NRC支持五、常见Bug大揭秘六、示例代码28_comm_ctl.c一、简介 根据ISO14119-1标准中所述,诊断服务28服务主要用于网络中的报文发送与接受,比如控制应用报文的发送与…

java支持3种网络编程模型,以及在web项目中的应用

之前有总结过linux中的5种IO模型 https://blog.csdn.net/weixin_45068892/article/details/127424119 本次主要讲一下java中支持的IO模型。 Java共支持3种网络编程IO模式&#xff0c;及应用场景 BIO NIO AIO https://blog.csdn.net/CSDN_GIA/article/details/128535848 BIO…

idea:解决jsp request.getParameter爆红的问题

文章目录 1. 复现错误2. 分析问题3. 解决问题 1. 复现错误 今天在写jsp代码时&#xff0c;出现如下错误&#xff1a; 2. 分析问题 这是没有引入相关jsp的相关jar包引起的。 我们可按如下步骤&#xff0c;引入jsp的相关jar包。 3. 解决问题 File -> Project Structure -&g…

【Truffle】二、自定义合约测试

一、准备测试 上期我们自己安装部署了truffle&#xff0c;并且体验了测试用例的整个测试流程&#xff0c;实际开发中&#xff0c;我们可以对自己的合约进行测试。 我们首先先明白自定义合约测试需要几个文件 合约文件&#xff1a;既然要测试合约&#xff0c;肯定要有合约的源码…

vue3 Teleport组件

<Teleport> 是一个内置组件&#xff0c;它可以将一个组件内部的一部分模板“传送”到该组件的 DOM 结构外层 的位置去。 <template><el-button click"dialogVisible true">打开弹窗</el-button><el-dialogv-model"dialogVisible&…

一文教你解决git请求github时候超时的问题

前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 一文教你解决git请求github的时候超时问题 一. 问题二. 当前 ssh 实现原理三. 创建ssh key3.1 将ssh key加入github配置中3.2 测试连…

洛谷P1765 手机 / 秋季赛 九宫格

手机 题目描述 一般的手机的键盘是这样的&#xff1a; 要按出英文字母就必须要按数字键多下。例如要按出 x \tt x x 就得按 9 9 9 两下&#xff0c;第一下会出 w \tt w w&#xff0c;而第二下会把 w \tt w w 变成 x \tt x x。 0 0 0 键按一下会出一个空格。 你的任务是…

算法笔记【6】-简单选择排序算法

文章目录 一、基本原理二、实现步骤三、优缺点分析 一、基本原理 在排序算法中&#xff0c;简单选择排序是一种基本且直观的排序方法。尽管它的性能较冒泡排序稍好&#xff0c;但仍然属于较慢的排序算法。本文将详细介绍简单选择排序算法的原理、步骤&#xff0c;并讨论其优缺…

AcWing第 127 场周赛 - AcWing 5283. 牛棚入住+AcWing 5284. 构造矩阵 - 模拟+快速幂+数学

AcWing 5283. 牛棚入住 题目数据范围不大&#xff0c;直接暴力模拟即可 按照题目所说的意思即可。 #include <math.h> #include <stdio.h> #include <algorithm> #include <cstring> #include <iostream> using namespace std; const int N 1…

清华训练营悟道篇之操作系统的内存管理

文章目录 SV39多级页表的硬件机制物理页帧的管理多级页表管理内核与应用的地址空间 SV39多级页表的硬件机制 三级页表 共3*9 27位虚拟页号 第 26-18 位为一级页索引 VPN0第 17-9 位为二级页索引 VPN1第 8-0 位为三级页索引 VPN2 每个页表都用 9 位索引 2^9 512 个页表项每个页…

数据结构-顺序表6

八.返回key的前驱下标&#xff0c;如果不存在&#xff08;key无前驱&#xff0c;在表头&#xff09;返回-1函数 思路&#xff1a;找到key的前驱&#xff0c;调用Search函数找key就可以 这里把i<0写成i<0&#xff0c;也是可以的&#xff0c;因为i0接着进入下面return i-1…

响应式相册写真摄影网站模板源码

模板信息&#xff1a; 模板编号&#xff1a;28526 模板编码&#xff1a;UTF8 模板颜色&#xff1a;黑白 模板分类&#xff1a;摄像、婚庆、家政、保洁 适合行业&#xff1a;婚纱摄影类企业 模板介绍&#xff1a; 本模板自带eyoucms内核&#xff0c;无需再下载eyou系统&#x…

springboot第44集:Kafka集群和Lua脚本

servers&#xff1a;Kafka服务器的地址。这是Kafka集群的地址&#xff0c;生产者将使用它来发送消息。retries&#xff1a;在消息发送失败时&#xff0c;生产者将尝试重新发送消息的次数。这个属性指定了重试次数。batchSize&#xff1a;指定了生产者在发送消息之前累积的消息大…

6.scala辅助构造器与为构造函数提供默认值(一)

概述 本文主要说明: 辅助构造器 与 为构造函数提供默认值 的使用 辅助构造器为构造函数提供默认值 相关链接 阅读之前&#xff0c;可以浏览一下 scala相关文章 辅助构造器 可以通过定义名为this的方法来定义辅助Scala类构造函数。只有几个规则需要了解&#xff1a; 每个辅助…

算法笔记【7】-直接插入排序算法

文章目录 一、简介二、基本原理和实现步骤三、优缺点分析 一、简介 在排序算法中&#xff0c;直接插入排序是一种基本而常用的排序方法。它通过不断将待排序数组中的元素插入到已排序部分的合适位置&#xff0c;逐步构建有序数组。本文将详细介绍直接插入排序算法的原理、实现…

2024王道考研计算机组成原理——总线

6.1 总线概述 每一个外设都通过IO接口和DB、CB、AB相连 三系统总线结构&#xff1a; 桥有总线仲裁的功能&#xff0c;就是把某一总线的使用权分给哪个设备&#xff1f; 6.1.2 总线的性能指标 总线复用&#xff1a;分时传输地址&数据 6.2 总线仲裁 通过控制总线来发送使…

《RT-DETR改进实战》专栏介绍 专栏目录

《RT-DETR改进实战专栏》介绍及目录 介绍&#xff1a;欢迎来到最新专栏《RT-DETR改进实战》&#xff01;这个专栏专注于基于 YOLOv8 项目的魔改版本&#xff0c;而不是百度飞桨框架中的 RT-DETR。 本专栏为想通过改进 RT-DETR 算法发表论文的同学设计。每篇文章均包含完整的改…

使用示例和应用程序全面了解高效数据管理的Golang MySQL数据库

Golang&#xff0c;也被称为Go&#xff0c;已经成为构建强大高性能应用程序的首选语言。在处理MySQL数据库时&#xff0c;Golang提供了一系列强大的库&#xff0c;简化了数据库交互并提高了效率。在本文中&#xff0c;我们将深入探讨一些最流行的Golang MySQL数据库库&#xff…

ImportError: DLL load failed while importing _pyopenvino: 找不到指定的程序

ImportError: DLL load failed while importing _pyopenvino: 找不到指定的程序 完全按照官方的pip安装方式&#xff0c;但是报错 解决方法&#xff1a; 下载下面压缩包 官网下载链接 解压到 运行程序之前 完成&#xff01;&#xff01;&#xff01; 测试 python -c &quo…

思维模型 纳什均衡

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。纳什均衡解释了囚徒困境、智猪博弈、内卷、美苏的军备竞赛等博弈问题。 1 纳什均衡的应用 1.1 经典的 囚徒困境 1 背景 囚徒困境是一个经典的博弈论问题&#xff0c;主要描述了两个被捕的…