SpringCloud之网关组件Gateway学习

news2024/11/20 7:18:11

SpringCloud之网关组件Gateway学习

GateWay简介

Spring Cloud Gateway是Spring Cloud的⼀个全新项目,目标是取代Netflix Zuul,它基于Spring5.0+SpringBoot2.0+WebFlux(基于高性能的Reactor模式响应式通信框架Netty,异步⾮阻塞模型)等技术开发,性能⾼于Zuul,官方测试,Gateway是Zuul的1.6倍,旨在为微服务架构提供种简单有效的统⼀的API路由管理方式。Spring Cloud Gateway不仅提供统的路由方式(反向代理)并且基于 Filter(定义过滤器对请求过滤,完成⼀些功能) 链的式提供了网关基本的功能,例如:鉴权、
流量控制、熔断、路径重写、日志监控等。

Gateway相关概念

Gateway使用

在项目中引入Gateway的依赖,这里要注意的是Gateway不支持Spring boot web包,所以需要排除掉spring-boot-starter-web

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

在微服务系统中,如果没有引入网关组件,用户的请求是直接请求到具体的服务的,而引入网关后,用户的请求会被网关组件处理,然后由网关组件将请求转发给具体的服务实例进行处理。网关组件也是一种服务,也需要被注册到Nacos等注册中心中。引入网关后的架构图如下所示:

在这里插入图片描述

Gateway服务配置,这一部分配置和其它的服务没有区别,是和Nacos注册中心集成的配置

server:
  port: 10010 #网关端口
spring:
  application:
    name: gatewayservice
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        group: testgroup1
        namespace: 8ff552f0-0212-43b2-8ea0-e4c2aa359084
        cluster-name: HZ

GateWay本身的配置如下:

spring:
  cloud:
    gateway: #路由匹配是从前往后,依次匹配的
      routes: #网关路由配置
      - id: providerservice  #路由id,需要唯一
        uri: lb://providerservice  # 路由的目标地址 lb就是负载均衡,后面跟服务名称
        predicates:  #路由断言,其实就是判断请求是否符合路由规则的条件
          - Path=/user/** #路由匹配 只要是以/user开头的请求就会匹配到,P需要大写,不然会报错
      - id: consumerservice
        uri: lb://consumerservice
        predicates:
          - Path=/consumer/**

然后在浏览器输入 http://localhost:10010/consumer/1,就可以访问到consumerservice服务了,这时因为GateWay服务将我们的请求根据配置的路由规则路由到了consumerservice。

路由断言工厂

路由断言工厂的作用是读取用户定义的断言条件,对请求作出判断。
我们上面的配置中的断言规则 Path=/user/** 只是字符串, 这些字符串会被Spring中的org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory处理的,类似的PredicateFactory在GateWay中还有很多。

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

上面这些路由断言工厂的具体使用,可以参考官方的路由断言工厂示例

过滤器

GateWay Filter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理。
在这里插入图片描述
Spring提供了31种不同的路由过滤器工厂,具体的使用可以参考官方的:

过滤器工厂官方示例

使用过滤器给请求添加一个请求头:

  cloud:
    gateway: #路由匹配是从前往后,依次匹配的
      routes: #网关路由配置
      - id: providerservice  #路由id,需要唯一
        uri: lb://providerservice  # 路由的目标地址 lb就是负载均衡,后面跟服务名称
        predicates:  #路由断言,其实就是判断请求是否符合路由规则的条件
          - Path=/user/** #路由匹配 只要是以/user开头的请求就会匹配到
      - id: consumerservice
        uri: lb://consumerservice
        predicates:
          - Path=/consumer/**
        filters:  #局部过滤器,只对某个服务起作用
          - AddRequestHeader=truth,This is a headr  #添加请求头

通过@RequestHeader注解来获取请求头的值
在这里插入图片描述
在控制台输出了获取到的请求头
在这里插入图片描述

如果想要过滤器对所有的路由都生效,可以把过滤器工厂写到default下

server:
  port: 10010 #网关端口
spring:
  application:
    name: gatewayservice
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        group: testgroup1
        namespace: 8ff552f0-0212-43b2-8ea0-e4c2aa359084
        cluster-name: HZ
    gateway: #路由匹配是从前往后,依次匹配的
      routes: #网关路由配置
      - id: providerservice  #路由id,需要唯一
        uri: lb://providerservice  # 路由的目标地址 lb就是负载均衡,后面跟服务名称
        predicates:  #路由断言,其实就是判断请求是否符合路由规则的条件
          - Path=/user/** #路由匹配 只要是以/user开头的请求就会匹配到
      - id: consumerservice
        uri: lb://consumerservice
        predicates:
          - Path=/consumer/**
        filters:
          - AddRequestHeader=truth,This is a headr  #添加请求头
      default-filters:
        - AddRequestHeader=truth,This is a headr1

前面提到的两种过滤器的过滤规则都是固定的,是框架给我们提供的;如果想要自定义过滤规则,则需要用到全局过滤器Global Filter。GateWay提供了GlobalFilter接口,只要我们实现这个接口就可以实现自定义的过滤器。重点是如何让过滤器链继续向下执行或者阻止过滤器链向下执行。下面是一个简单的全局过滤器示例:

/**
 * @author DELL
 * @version 1.0
 * @description
 * @date 2024/3/13 22:38:05
 */
@Order(value = 1)  #指定过滤器的执行顺序,值越小越先执行
public class MyGlobalFilter implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //获取请求参数
        MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();

        //获取
        String authorization = params.getFirst("authorization");

        //校验
        if ("admin".equals(authorization)) {
            //放行
            return chain.filter(exchange);
        }

        //拦截
        exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
        
        return exchange.getResponse().setComplete();
    }

}

上面提到了三种过滤器,某个服务的过滤器(filters)、默认的过滤器(default-filters)、全局过滤器(GlobalFilter),如果三种过滤器都进行了配置,那么它们的执行顺序如下:

在这里插入图片描述

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

CROS配置

Gateway中进行跨域的配置如下:

spring:
  application:
    name: gatewayservice
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        group: testgroup1
        namespace: 8ff552f0-0212-43b2-8ea0-e4c2aa359084
        cluster-name: HZ
    gateway: #路由匹配是从前往后,依次匹配的
      routes: #网关路由配置
      - id: providerservice  #路由id,需要唯一
        uri: lb://providerservice  # 路由的目标地址 lb就是负载均衡,后面跟服务名称
        predicates:  #路由断言,其实就是判断请求是否符合路由规则的条件
          - Path=/user/** #路由匹配 只要是以/user开头的请求就会匹配到
      - id: consumerservice
        uri: lb://consumerservice
        predicates:
          - Path=/consumer/**
        filters:
          - AddRequestHeader=truth,This is a headr  #添加请求头
      default-filters:
        - AddRequestHeader=truth,This is a headr1
        
      globalcors:  #跨域配置
        cors-configurations:
          '[/**]':
            allowedOrigins: "http://localhost:8090"  #允许哪些请求跨域
            allowedMethods:  #允许的跨域的请求方式
              - GET
            allowedHeaders: "*"   允许在请求中携带的头信息
            allowCredentials: true # 是否允许携带cookie
            maxAge: 36000 #跨域检测有效期

参考

  1. Gateway官方文档

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

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

相关文章

每日一题 --- 977. 有序数组的平方[力扣][Go]

今天这一题和昨天的知识点是一样的&#xff0c;就是双指针法。 题目&#xff1a; 给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每个数字的平方 组成的新数组&#xff0c;要求也按 非递减顺序 排序。 示例 1&#xff1a; 输入&#xff1a;nums [-4,-1,0,3,1…

Zero-Change Object Transmission for Distributed Big Data Analytics——论文泛读

ATC 2022 Paper 问题 分布式大数据分析在很大程度上依赖于Java和Scala等高级语言的可靠性和多功能性。然而&#xff0c;这些高级语言也为数据传输制造了障碍。要在Java虚拟机&#xff08;JVM&#xff09;之间传输数据&#xff0c;发送方应将对象转换为字节数组&#xff08;序…

ArmSoM-Sige RK3588开发板产品简介

让我们在 5 分钟内了解 Sige7。 简介​ ArmSoM-Sige7采用Rockchip RK3588新一代旗舰级八核64位处理器&#xff0c;主频高达2.4GHz&#xff0c;6 TOPS算力NPU&#xff0c;最大可配32GB大内存。支持8K视频编解码&#xff0c;拥有丰富的接口&#xff0c;支持双2.5G网口、WiFi6 &…

虚拟机开机启动失败,进入(initramfs)解决办法

虚拟机开机启动失败&#xff0c;进入&#xff08;initramfs&#xff09;解决办法 打开虚拟机中Ubuntu时进入(initramfs)&#xff0c;导致无法进入桌面。问题如下图显示&#xff1a; 命令行输入 fsck -y /dev/sda5输入 exit进入 选择root 后回车 输入虚拟机的密码 进入 root …

项目成功秘诀:高效管理策略确保按时交付v2

一、项目成功的重要性 在当今竞争激烈的商业环境中&#xff0c;项目的成功对于企业的生存和发展具有至关重要的意义。项目的成功不仅意味着企业能够达成既定的业务目标&#xff0c;还能提升企业的市场地位、增强品牌影响力&#xff0c;并为企业的可持续发展奠定坚实基础。我们…

C++ Primmer 12.3文本查询程序(自己原来写的,跟课本中比较)

题目要求如下 1.自己版本 #pragma once #include <fstream> #include <string> #include <vector> #include <set> #include <map> #include <iostream> #include <sstream>using namespace std;int main() {ifstream t_if (&quo…

乱码问题,字符流原理

首先科普一下知识&#xff0c;我们知道ASCII码中有128的数字&#xff0c;符号&#xff0c;或大小写字母&#xff0c;这对于英文来说已经够用了&#xff0c;一个字母占用一个字节&#xff08;一个字节8bit&#xff09;&#xff0c; 存储的过程是这样的&#xff0c;一个字母w&…

二进制王国(蓝桥杯备赛)【sort/cmp的灵活应用】

二进制王国 题目链接 https://www.lanqiao.cn/problems/17035/learning/?contest_id177 题目描述 思路 这里就要灵活理解字典序排列&#xff0c;虽然string内置可以直接比较字符串字典序&#xff0c;但是在拼接时比较特殊&#xff0c;比如 11的字典序小于110&#xff0c;但…

鸿蒙Harmony应用开发—ArkTS(@Extend装饰器:定义扩展组件样式)

在前文的示例中&#xff0c;可以使用Styles用于样式的扩展&#xff0c;在Styles的基础上&#xff0c;我们提供了Extend&#xff0c;用于扩展原生组件样式。 说明&#xff1a; 从API version 9开始&#xff0c;该装饰器支持在ArkTS卡片中使用。 装饰器使用说明 语法 Extend(UI…

4 种策略让 MySQL 和 Redis 数据保持一致

先阐明一下 MySQL 和 Redis 的关系&#xff1a;MySQL 是数据库&#xff0c;用来持久化数据&#xff0c;一定程度上保证数据的可靠性&#xff1b;Redis 是用来当缓存&#xff0c;用来提升数据访问的性能。 关于如何保证 MySQL 和 Redis 中的数据一致&#xff08;即缓存一致性问题…

jmeter超高并发报错解决方法

1、比如jmeter设置并发量为5000&#xff0c;运行后报错socket closed。原因是客户端与服务端做了三次握手之后&#xff0c;后面不需要握手了&#xff0c;但是jmeter没有这个功能&#xff0c;5000个并发每次发接口请求都是独立的&#xff0c;jmeter端口处理不了这么大量的请求&a…

【SpringBoot框架篇】37.使用gRPC实现远程服务调用

文章目录 RPC简介gPRC简介protobuf1.文件编写规范2.字段类型3.定义服务(Services) 在Spring Boot中使用grpc1.父工程pom配置2.grpc-api模块2.1.pom配置2.2.proto文件编写2.3.把proto文件编译成class文件 3.grpc-server模块3.1.pom文件和application.yaml3.2.实现grpc-api模块的…

01. 如何配置ESP32环境?如何开发ESP32?

0. 前言 此文章收录于《ESP32学习笔记》专栏&#xff0c;此专栏会结合实际项目记录作者学习ESP32的过程&#xff0c;争取每篇文章能够将细节讲明白&#xff0c;会应用。 1. 安装IDE&#xff1a;Thonny 后续项目中我们都是使用pythont语言&#xff0c;而thonny工具能很好的支撑E…

Vue3:用重定向方式,解决No match found for location with path “/“问题

一、情景说明 在初学Vue3的项目中&#xff0c;我们配置了路由后&#xff0c;页面会告警 如下图&#xff1a; 具体含义就是&#xff0c;没有配置"/"路径对应的路由组件 二、解决 关键配置&#xff1a;redirect const router createRouter({history:createWebHis…

P1246 编码题解

题目 编码工作常被运用于密文或压缩传输。这里我们用一种最简单的编码方式进行编码&#xff1a;把一些有规律的单词编成数字。 字母表中共有26个字母a,b,c,⋯,z&#xff0c;这些特殊的单词长度不超过6且字母按升序排列。把所有这样的单词放在一起&#xff0c;按字典顺序排列&…

【docker系列】深入理解 Docker 容器管理与清理

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

C语言内存函数(1)【memcpy函数的使用与模拟实现】【memmove函数的使用和模拟实现】

关于内存函数有四个函数需要我们学习。分别是memcpy&#xff0c;memmove&#xff0c;memset和memcmp。都在头文件string.h里面。 一.memcpy函数的使用 一提到这个函数&#xff0c;我们可能会联想到strcpy函数&#xff0c;但strcpy函数是针对字符串的拷贝。但是我们在写代码的…

Docker学习笔记 - 基本概念

一. 什么是“容器”&#xff08;container&#xff09;和“镜像”&#xff08;Image&#xff09; 所谓“容器”可以理解为一个模拟操作系统的虚拟层&#xff0c;大部分是基于Linux的&#xff0c;应用程序及其配置信息&#xff0c;依赖库可以打包成一个Image独立运行在这个虚拟…

双指针算法:三数之和

文章目录 一、[题目链接&#xff1a;三数之和](https://leetcode.cn/problems/3sum/submissions/515727749/)二、思路讲解三、代码演示 先赞后看&#xff0c;养成习惯&#xff01;&#xff01;&#xff01;^ _ ^<3 ❤️ ❤️ ❤️ 码字不易&#xff0c;大家的支持就是我坚持…

【LeetCode】升级打怪之路 Day 28:回溯算法 — 括号生成 删除无效的括号

今日题目&#xff1a; 22. 括号生成301. 删除无效的括号 参考文章&#xff1a; 回溯算法&#xff1a;括号生成回溯算法&#xff1a;删除无效的括号 这是两道使用回溯算法来解决与括号相关的问题&#xff0c;具备一定的难度&#xff0c;需要学习理解。 通过第一道题“括号生成”…