gateway的使用

news2025/3/11 3:06:29

什么是Spring Cloud Gateway

网关作为流量的入口,常用的功能包括路由转发,权限校验,限流等。
Spring Cloud Gateway 是Spring Cloud官方推出的第二代网关框架,定位于取代 Netflix Zuul。相比 Zuul 来说,Spring Cloud Gateway 提供更优秀的性能,更强大的有功能。
SpringCloud Gateway 是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关。为了提升网关的性能,SpringCloud Gateway 是基于 WebFlux 框架实现的,而 WebFlux 框架底层则使用了高性能的 Reactor 模式通信框架 Netty。
Spring Cloud Gateway 是由 WebFlux 实现的响应式的 API 网关。它不能在传统的 servlet 容器中工作,也不能构建成 war 包。
Spring Cloud Gateway 旨在为微服务架构提供一种简单且有效的 API 路由的管理方式,并基于 Filter 的方式提供网关的基本功能,例如说安全认证、监控、限流等等。

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

核心概念

路由(route)

路由是网关中最基础的部分,路由信息包括一个ID、一个目的URI、一组断言工厂、一组Filter组成。如果断言为真,则说明请求的URL和配置的路由匹配。

断言(predicates)

Java8中的断言函数,SpringCloud Gateway中的断言函数类型是Spring5.0框架中的ServerWebExchange。断言函数允许开发者去定义匹配Http request中的任何信息,比如请求头和参数等。

过滤器(Filter)

SpringCloud Gateway中的filter分为Gateway FilIer和Global Filter。Filter可以对请求和响应进行处理。

工作原理

Spring Cloud Gateway 的工作原理跟 Zuul 的差不多,最大的区别就是 Gateway 的 Filter 只有 pre 和 post 两种。
在这里插入图片描述

客户端向 Spring Cloud Gateway 发出请求。
如果 Gateway Handler Mapping 找到与请求相匹配的路由,将其发送到 Gateway Web Handler。
Handler 再通过指定的 过滤器链 来将请求发送到我们实际的服务执行业务逻辑,然后返回。
过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执行业务逻辑。

Spring Cloud Gateway快速开始

环境搭建

  1. 引入依赖
<!-- gateway网关 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

<!-- nacos服务注册与发现 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

注意:会和spring-webmvc的依赖冲突,需要排除spring-webmvc
2) 编写yml配置文件

server:
  port: 8877

spring:
  application:
    name: ahs-gateway
  cloud:
  #  nacos注册中心
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      discovery:
        locator:
          enabled: false #默认为false,设为true开启通过微服务创建路由的功能,即可以通过微服务名访问服务
          lower-case-service-id: true
      enabled: true # 是否开启网关
      routes:
        - id: ahs-user-route
          uri: lb://ash-user
          #uri: http://www.baidu.com
          predicates:
            - Path=/user/test123
          filters:
            # ??
            # ??????
            - StripPrefix=1

路由断言工厂(Route Predicate Factories)配置
官方文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

gateway自身提供的路有断言工厂
在这里插入图片描述

时间匹配
可以用在限时抢购的一些场景中。

spring:
  cloud:
    gateway:
      routes:
      - id: after_route #全局唯一自己随便定义
        uri: https://example.org:8080 #目标微服务请求的地址和端口
        # 测试url:https://example.org:8080/test
        predicates:
       # - After=2017-01-20T17:42:47.789-07:00[America/Denver] # 美国的时区
       # 在时间之后 当然也有- Before
        - After=2017-01-20T17:42:47.789-07:00[Asia/Shanghai] # 亚洲上海市区

请求的时间必须在after配置的之后

before时间断言工厂配置

spring:
  cloud:
    gateway:
      routes:
      - id: before_route
        uri: https://example.org
        predicates:
        - Before=2017-01-20T17:42:47.789-07:00[America/Denver]

请求的时间必须在Before配置的之前

betwen断言工厂配置

spring:
  cloud:
    gateway:
      routes:
      - id: between_route
        uri: https://example.org
        predicates:
        - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

请求的时间必须在betwen配置时间之间

Cookie断言共产匹配

spring:
  cloud:
    gateway:
      routes:
      - id: cookie_route
        uri: https://example.org
        predicates:
        - Cookie=chocolate, ch.p  # k v 健值对

就是一个键值对!请求的Cookie必须要有一个键值对chocolate:ch.p。满足我就给你访问

Header匹配
spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
# Header匹配 请求中带有请求头名为 x-request-id,其值与 \d+ 正则表达式匹配
- Header=X-Request-Id, \d+

这个路由规则匹配Header中包含X-Request-Id并且值为纯数字的请求。

主机路有断言匹配

spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: https://example.org
        predicates:
        - Host=**.somehost.org,**.anotherhost.org

请求http://localhost:8080 -H “Host: www.somehost.org” 可以请求通过

2.2.4 路径匹配

  routes:
    - id: provider_routh
      uri: lb://SPRINGCLOUD-PROVIDER-DEPT   #目标微服务名!而且是以负载均衡方式去获取!
      predicates:    						#断言
        - Path=/testGateWay01

请求的路中必须包含testGateWay01

Method 路由断言

routes:
- id: provider_routh
uri: lb://SPRINGCLOUD-PROVIDER-DEPT #目标微服务名!而且是以负载均衡方式去获取!
predicates: #断言
- Path=/testGateWay01
- Method=GET,POST

这个路由匹配所有的GET POST请求,并且请求的前缀是testGateWay01。

.Query 查询路由断言


      routes:
        - id: provider_routh
          uri: lb://SPRINGCLOUD-PROVIDER-DEPT   #目标微服务名!而且是以负载均衡方式去获取!
          predicates:    						#断言
            - Path=/testGateWay01
            - Query=green
            - Query=red, gree.

1.如果请求中包含green的参数,则匹配成功。
2.如果一个请求中包含参数red并且值匹配·gree.·这个正则,那么路由匹配。比如:green和greet。

2.2.5 自定义路由断言工厂
自定义路由断言工厂需要继承 AbstractRoutePredicateFactory 类,重写 apply 方法的逻辑。在 apply 方法中可以通过 exchange.getRequest() 拿到 ServerHttpRequest 对象,从而可以获取到请求的参数、请求方式、请求头等信息。
注意: 命名需要以 RoutePredicateFactory 结尾

1、 必须spring组件 bean
2、类必须加上RoutePredicateFactory作为结尾
3、必须继承AbstractRoutePredicateFactory
4、必须声明静态内部类 声明属性来接收 配置文件中对应的断言的信息
5、 需要结合shortcutFieldOrder进行绑定
6、通过apply进行逻辑判断 true就是匹配成功 false匹配失败

@Component
@Slf4j
public class CheckAuthRoutePredicateFactory extends AbstractRoutePredicateFactory<CheckAuthRoutePredicateFactory.Config> {

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

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return new GatewayPredicate() {

            @Override
            public boolean test(ServerWebExchange serverWebExchange) {
                log.info("调用CheckAuthRoutePredicateFactory" + config.getName());
                if(config.getName().equals("www")){
                    return true;
                }
                return false;
            }
        };
    }

    /**
     * 快捷配置
     * @return
     */
    @Override
    public List<String> shortcutFieldOrder() {
        return Collections.singletonList("name");
    }

    public static class Config {

        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

yml中配置

spring:
  cloud:
    gateway:
      #设置路由:路由id、路由到微服务的uri、断言
      routes:
      - id: order_route  #路由ID,全局唯一
        uri: lb://test-service  #目标微服务的请求地址和端口
        predicates:
        # 测试路径 http://localhost:8080/test123/api/change
        - Path=/test123   #Path路径匹配
        # 自定义CheckAuth断言工厂
        - CheckAuth=www   
        filters:
            - StripPrefix=1 # 转发之前去掉1层路径  变成 -> http://localhost:8080/api/change

过滤器工厂( GatewayFilter Factories

GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理

在这里插入图片描述

SpringCloudGateway 内置了很多的过滤器工厂,我们通过一些过滤器工厂可以进行一些业务逻辑处理器,比如添加剔除响应头,添加去除参数等

spring:
  cloud:
    gateway:
      routes: # 网关路由配置
        - id: user-service
          uri: lb://userservice
          predicates:
            - Path=/user/**
          filters: # 过滤器
            - AddRequestHeader=info, AddRequestHeader! # 添加请求头

userservice项目中controller中的请求方法上获取Info的内容

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/{id}")
    public User queryByid(@PathVariable("id") Long id,
                          @RequestHeader(value = "Info",required = false) String info) {
        System.out.println(info);
        return userService.queryById(id);
    }
}

默认过滤器
如果要对所有的路由都生效,则可以将过滤器工厂写到default下。格式如下

spring:
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
          #filters: # 过滤器
          #  - AddRequestHeader=info, AddRequestHeader! # 添加请求头
        - id: feign-order-service
          uri: lb://feignorderservice
          predicates:
            - Path=/order/**
          filters:
          	- PrefixPath=/mall-order  # 添加前缀 对应微服务需要配置context-path
      default-filters: # 默认过滤器,会对所有的路由请求都生效
        - AddRequestHeader=Info,'default filers request header!' # 添加请求头

为匹配的路由统一添加前缀

spring:
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
        - id: feign-order-service
          uri: lb://feignorderservice
          predicates:
            - Path=/order/**
          filters:
          	- PrefixPath=/api  # 添加前缀 对应微服务需要配置context-path

对应为服务中需要票配置

server:
  servlet:
    context-path: /api

重定向操作

spring:
  cloud:
    gateway:
      #设置路由:路由id、路由到微服务的uri、断言
      routes:
      - id: user-service  #路由ID,全局唯一
        uri: lb://userservice #目标微服务的请求地址和端口
        #配置过滤器工厂
        predicates:
        - Path=/order/**
        filters:
        - RedirectTo=302, https://www.baidu.com/  #重定向到百度

自定义过滤器工厂
继承AbstractNameValueGatewayFilterFactory且我们的自定义名称必须要以GatewayFilterFactory结尾并交给spring管理。

@Component
@Slf4j
public class CheckAuthGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {

    @Override
    public GatewayFilter apply(NameValueConfig config) {
        return (exchange, chain) -> {
            log.info("调用CheckAuthGatewayFilterFactory==="
                    + config.getName() + ":" + config.getValue());
            return chain.filter(exchange);
        };
    }
}
配置自定义的过滤器工厂
spring:
  cloud:
    gateway:
      #设置路由:路由id、路由到微服务的uri、断言
      routes:
      - id: user-service  #路由ID,全局唯一
        uri: lb://userservice #目标微服务的请求地址和端口
        #配置过滤器工厂
        predicates:
        - Path=/order/**
        #配置过滤器工厂
        filters:
        - CheckAuth=www,女

全局过滤器(Global Filters)配置

GlobalFilter 接口和 GatewayFilter 有一样的接口定义,只不过, GlobalFilter 会作用于所有路由。
官方声明:GlobalFilter的接口定义以及用法在未来的版本可能会发生变化。
LoadBalancerClientFilter
LoadBalancerClientFilter 会查看exchange的属性 ‘ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 的值(一个URI),如果该值的scheme是 lb,比如:lb://myservice ,它将会使用Spring Cloud的LoadBalancerClient 来将 myservice 解析成实际的host和port,并替换掉 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 的内容。
其实就是用来整合负载均衡器Ribbon的

需求:定义全局过滤器,拦截请求,判断请求的参数是否满足下面条件:
参数中是否有authorization,
authorization参数值是否为admin
如果同时满足则放行,否则拦截

自定义全局过滤器

/@Order(-1) //过滤器执行顺序
@Component //spring容器管理
public class AuthorizationFilter implements GlobalFilter, Ordered {
    @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();
    }

    @Override
    public int getOrder() {
        return -1;
    }
}

注意:Order注解和implements Ordered作用是完全一样的,二选一即可。

过滤器加载流程

在这里插入图片描述

org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#getFilters()方法是先加载defaultFilters,然后再加载某个route的filters,然后合并。
org.springframework.cloud.gateway.handler.FilteringWebHandler#handle()方法会加载全局过滤器,与前面的过滤器合并后根据order排序,组织过滤器链

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

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

相关文章

第1章 量化设计与分析基础

1.1 引言 如今一台价格不足500美元的手机&#xff0c;性能便堪比1993年世界上最快的售价5000万美元的计算机&#xff0c;这种快速发展既得益于计算机制造技术的发展&#xff0c;也得益于计算机设计的创新。 纵观计算机发展的历史&#xff0c;技术一直在稳定地提升&#xff0c…

【COT】Chain-of-Thought Prompting Elicits Reasoning in Large Language Models

文章目录 主要解决什么问题采用什么方法实验分析与结果消融实验Commonsense ReasoningSymbolic Reasoning 问题与展望 Chain-of-Thought Prompting Elicits Reasoning in Large Language Models 主要解决什么问题 大语言模型越来越大&#xff0c;效果越来越好。但是在一些具有…

Sui Builder House首尔站|主网上线后首次亮相

Sui Builder House提供与全球Sui构建者会面、合作并学习Sui平台前沿技术的机会。Sui基金会计划将于2023年在全球12个城市举办Sui Builder House。截止目前&#xff0c;已成功在美国丹佛市、越南胡志明市和中国香港举办三场Builder House活动。 Sui Builder House首尔站将于6月…

【D435i深度相机YOLO V5结合实现目标检测】

【D435i深度相机YOLO V5结合实现目标检测】 1. 前言2 分析2.1 关于yolo部分2.2 关于获取三维坐标的部分2.3 关于文件结构部分 3. 代码 1. 前言 参考&#xff1a;Ubutntu下使用realsense d435i&#xff08;三&#xff09;&#xff1a;使用yolo v5测量目标物中心点三维坐标 欢迎大…

满意度指标- NPS 的ABtest(公式推导)

&#x1f449;A 组的NPS如下 &#x1f449;B 组的NPS如下 &#xff08;下标为1&#xff0c;均为A组的样本数据&#xff1b;下标为2&#xff0c;均为B组的样本数据&#xff09; 要验证A\B两组的NPS差异是否显著&#xff0c;可通过假设检验。 一、假设检验前置准备 1. 选择…

FastDFS理论与Java程序的对接(图片,文件上传)

目录 fastdfs概述Java程序对接fastDFSpom配置java启动类注解yaml文件配置controller类service类 fastdfs概述 什么是分布式文件系统&#xff1f; 是指文件系统管理的物理存储资源不一定直接连接在本地节点上&#xff0c;而是通过计算机与节点相连。 通俗来讲&#xff1a; 传统…

【medini analyze 软件介绍】

medini analyze 软件介绍 简介主要功能&#xff08;功能安全范畴&#xff09;1、HARA2、建模3、FMEA & FMEDA4、FTA*这里只是笔者根据汽车功能安全分析经验简单列举了medini analyze的部分功能&#xff0c;完整的功能介绍请参考ANSYS官网* 简介 medini analyze是一款专业的…

怎么把pdf文件压缩到最小?四招快速压缩!

怎么把pdf文件压缩到最小&#xff1f;平常我们要压缩一个文件&#xff0c;一般都知道该如何操作。系统中自带了压缩工具&#xff0c;只需右键点击需要压缩的对象并选择"压缩"选项即可完成操作。然而&#xff0c;很多人也会发现&#xff0c;尽管大部分的文件都可以通过…

网络安全公司Dragos披露网络安全事件

工业网络安全公司 Dragos 披露了它所称的“网络安全事件”&#xff0c;此前一个已知的网络犯罪团伙试图突破其防御并渗透到内部网络以加密设备。 虽然 Dragos 表示威胁行为者没有破坏其网络或网络安全平台&#xff0c;但他们可以访问公司的 SharePoint 云服务和合同管理系统。…

05-HTML-图片标签

<img> 标签&#xff1a;src 属性是必需的。它规定图像的 URL。 绝对 URL - 指向另一个网站&#xff08;比如 src"http://www.example.com/image.gif"&#xff09;相对 URL - 指向网站内的一个文件&#xff08;比如 src"image.gif"&#xff09; <…

网络层最重要的协议—IP协议

网络层最重要的协议—IP协议 IP协议格式解决IP地址不够用问题的三种方法方法一: 动态分配IP地址方法二: NAT网络地址转换方法三: IPv6(根本上解决IP不够用的问题)小结&#xff1a; IP协议之地址管理主机号/网络号子网掩码特殊IP IP协议格式 4位版本&#xff1a;此处取4或64位首…

sort ,uniq ,tr ,cut命令

目录 一、sort命令 1.格式 2.命令演示 2.1 选项 -n :按照数字大小排序 2.2选项 -r &#xff1a;反向排序 2.3选项 -u&#xff1a;隐藏多余行 2.4选项 -t &#xff1a;指定分隔符&#xff1b;-k &#xff1a;指定字符&#xff1b;-o &#xff1a;指定保存文件 二、uniq命令…

Git的安装与版本控制

这里写目录标题 原理安装基本使用gitee-IDEA协同开发成员邀请开发组成员指定仓库权限给当前仓库设定分支提交代码时必须向自己的分支提交合并分支 - 无冲突 原理 Git本地有四个工作区域&#xff1a; 工作目录&#xff08;Working Directory&#xff09;、暂存区(Stage/Index)、…

【Linux】笔记分享

目录 - 前言- 目录结构- 磁盘文件系统- 文件权限 ls -l 的内容文件及目录权限实际案例 修改权限 -chmod[change ...]第一种方式&#xff1a; 、-、 变更权限第二种方式&#xff1a;通过数字变更权限 修改文件所有者 -chown 修改文件所在组 -chgrp - 命令类型基础命令网络性能…

【数据类型-列表】------- PYTHON基础9

内容目录 一、数据类型-列表1. 列表1.1. 列表的截取 result List[start:end:step]1.2. 列表元素的修改 List[index] element1.3. 列表元素的删除 del List[index] 或 del List[start:end:step]1.4. 列表元素的拼接 “” 或者增量赋值运算符 “” 2. 列表常用内置函数 对象.内…

jdbc工具包

JDBC工具类 介绍 JDBC全称是Java数据库连接&#xff08;Java Database connect&#xff09;&#xff0c;它是一套用于执行SQL语句的JavaAPI。应用程序可通过这台API连接到关系数据库&#xff0c;并使用SQL语句来完成对数据库中数据的查询、更新和删除等操作。 JDBC实现细节 从…

深入浅出C语言——排序

文章目录 排序的概念常见的排序算法冒泡排序选择排序插入排序希尔排序堆排序快速排序hoare版本挖坑法前后指针版本快速排序的非递归形式 归并排序递归版本非递归版本 计数排序排序算法复杂度及稳定性分析 排序的概念 排序就是使用使一串记录&#xff0c;按照其中的某个或某些关…

vue3 nextTick()应用

在Vue3中&#xff0c;可以使用nextTick函数来延迟执行某些操作&#xff0c;这些操作会在下一次DOM更新周期之后执行。这个函数通常用于在数据更新后&#xff0c;等待DOM更新之后执行一些操作&#xff0c;比如获取DOM元素的尺寸、位置等。 nextTick() 例如&#xff0c;以下一个…

C语言—与坤(机)对弈

目录 设计思路 游戏运行效果 函数的声明 头文件game.h 游戏主体(源文件) 1.game.c 2.test.c 各文件的阐述 各部分的设计心得 1.打印菜单 2.初始化棋盘 3.打印棋盘 棋盘最终效果 1.打印数据 2.打印分割线 如何扩展为10 x 10 棋盘&#xff1f; 4.玩家下棋、电脑下…

mkv文件怎么转换成mp4?来看看这四种转换方式吧!

mkv文件怎么转换成mp4&#xff1f;在很多小伙伴看到&#xff0c;图片就是图片&#xff0c;音频就是音频&#xff0c;视频就是视频&#xff0c;它们展现给人们的效果都差不多。但实际上&#xff0c;不管是图片、视频还是音频文件&#xff0c;其中一个重要的区别在于它们的文件格…