当前位置: 首页 > news >正文

Gateway实战入门(四)、断言-请求头以及请求权重分流等

spring cloud-Gateway:断言-请求头以及请求权重分流等

    • 一、断言Header信息要求
      • 项目前置环境要求
      • 案例一、断言-请求头信息-匹配X-Request-Id
        • 1、配置文件及代码
        • 2、测试
      • 案例二、断言-请求头信息-匹配API版本
        • 场景
        • 主要配置信息
      • 案例三、断言-请求头信息:匹配请求来源
        • 场景
        • 主要配置信息
      • 案例四、断言-请求头信息:匹配用户权限/角色
        • 场景
        • 主要配置信息
    • 二、断言-请求方式
      • 案例、请求方式Demo
        • 主要配置信息
        • 测试
    • 三、断言-查询条件
      • 案例、断言-查询条件QueryDemo
        • 主要配置信息
        • 测试
    • 四、断言-将请求按设定的权重进行分流
      • 涉及到要用权重分流的场景
      • 案例、断言-WeightDemo
        • 主要配置信息
        • 测试

一、断言Header信息要求

需要参数header 和regexp(正则表达式),即key和value,匹配请求携带的信息。实际就是对应请求头携带的信息,官网的案例是X-Request-Id,所以我们第一个案例就以它为例 ;)

项目前置环境要求

  • 启动nacos服务,对应版本: 2.2.3 ,jdk1.8或以上。
  • 至少1个服务提供者,端口9001,提供一个web接口,【我的是/hello,下文也是以此接口为例】;
  • 一个网关服务端口 9966 ;

案例一、断言-请求头信息-匹配X-Request-Id

1、配置文件及代码

网关gateway的yaml配置文件:

server:
  port: 9966
spring:
  application:
    name: gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.0.103:80
    gateway:
      discovery:
        locator:
          enabled: false # 关闭注册中心路由功能
      routes:
        - id: nacos-provider
          uri: lb://nacos-provider #路由到注册中心,服务为nacos-provider的服务
          predicates:
            - Path=/nancy/** # 路径匹配,则进行路由
            - Header=X-Request-Id,\d+ #表示数字
          filters:
            - StripPrefix=1 # 截取掉断言路径的第一部分
management:
  endpoint:
    web:
      exposure:
        include: '*'

网关gateway主启动类:

package com.nancy.gateway9966;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

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

服务提供者9001,接口

/**
 * @Auther: gina
 * @Date: 2025-03-10
 * @Description:
 */
@RestController
@Slf4j
public class UserController {

    @GetMapping("/hello")
    public String hello(HttpServletRequest request) {
        log.info("........Nacos Provider run.......... ");
        return "9001-----hello Nancy...";
    }
}

服务提供者yaml

server:
  port: 9001

spring:
  application:
    name: nacos-provider
  cloud:
    discovery:
      server-addr: 192.168.0.103:80
management:
  endpoint:
    web:
      exposure:
        include: '*'

服务提供者主启动类

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

}

服务提供者,引入maven依赖

 		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
2、测试

启动9001服务,gateway9966网关侧服务。访问链接:http://localhost:9966/nancy/hello
在这里插入图片描述

案例二、断言-请求头信息-匹配API版本

场景

案例一的粒度要粗一些,属于服务之间的隔离;但实际工作中会有粒度更细的场景,比如API 可以同时存在多个版本的场景,举个实际场景的例子:
手机APP,新业务迭代,对于老版本app也要做兼容,但老app界面框架无法更改(涉及到合规和用户体验的考量,一般不会选择强制更新),这时就会有相同业务不同api版本的诉求。

而落地实现的方式之一,可以基于spring cloud 的gateway 的断言来实现,通过断言做API版本隔离,不同版本路由到不同的服务;话不多说直接上实例。

主要配置信息

网关gateway9966的yaml文件关于路由的内容设置:

 spring:
  cloud:
    gateway:
      routes:
        - id: route_api_v1
          uri: http://nacos-consumer/testV1
          predicates:
            - Header=X-API-Version, 1.1.0  # 如果 API 版本为 1.1.0,则路由到 v1 服务
        - id: route_api_v2
          uri: http://nacos-consumer/testV2
          predicates:
            - Header=X-API-Version, 1.2.0  # 如果 API 版本为 1.2.0,则路由到 v2 服务

测试同案例一,不再赘述。

案例三、断言-请求头信息:匹配请求来源

场景

在处理跨域请求时,会在请求Header中添加Origin字段。使用Header断言可以根据Origin字段的值判断请求的来源,从而设定只限某些来源的请求来访问资源。

主要配置信息

gateway网关侧yaml文件主要配置信息如下:

spring:
  cloud:
    gateway:
      routes:
        - id: allowed_origin_route
          uri: http://backend-service
          predicates:
            - Header=Origin, https://nancy.com  # 只允许来自 https://nancy.com 的请求

案例四、断言-请求头信息:匹配用户权限/角色

场景

微服务架构中,在请求Header里可能会增加用户的角色信息,比如X-User-Role。基于 此断言的Header信息里用户的角色,将请求路由到不同的资源或服务。

主要配置信息

gateway网关侧yaml文件主要配置信息如下:

spring:
  cloud:
    gateway:
      routes:
        - id: admin_route
          uri: http://nacos-consumer/admin
          predicates:
            - Header=X-User-Role, admin  # 用户角色是管理员,则路由到admin服务
        - id: user_route
          uri: http://nacos-consumer/user
          predicates:
            - Header=X-User-Role, user  # 用户角色是普通用户,则路由到user服务

二、断言-请求方式

Method:可以设置一个或多个参数,匹配HTTP请求,比如GET、POST

案例、请求方式Demo

主要配置信息
server:
  port: 9966
spring:
  application:
    name: gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.0.103:80
    gateway:
      discovery:
        locator:
          enabled: false # 开启注册中心路由功能
      routes:
        - id: nacos-provider
          uri: lb://nacos-provider #路由到注册中心,服务为nacos-provider的服务
          predicates:
            - Path=/nancy/** # 路径匹配,则进行路由
            - Method=POST,GET # 匹配GET请求或者POST请求

          filters:
            - StripPrefix=1 # 截取掉断言路径的第一部分
management:
  endpoint:
    web:
      exposure:
        include: '*'
测试

访问路径:http://localhost:9966/nancy/hello
1、代码中设置的请求方式只有post和get两种,如果访问put方式,会报404,如图:
在这里插入图片描述
2、如果请求方式设置为get,则接口是通的,由网关路由到9002端口的hello接口,如下图:
在这里插入图片描述

三、断言-查询条件

案例、断言-查询条件QueryDemo

Query:需要指定一个或者多个参数,一个必须参数和一个可选的正则表达式,匹配请求中是否包含第一个参数,
如果有两个参数,则匹配请求中第一个参数的值是否符合正则表达式。

主要配置信息

gateway的配置信息

server:
  port: 9966
spring:
  application:
    name: gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.0.103:80
    gateway:
      discovery:
        locator:
          enabled: false # 开启注册中心路由功能
      routes:
        - id: nacos-provider
          uri: lb://nacos-provider #路由到注册中心,服务为nacos-provider的服务
          predicates:
            - Path=/nancy/** # 路径匹配,则进行路由
            - Query=id,.+ # 匹配请求参数,这里如果需要匹配多个参数,可以写多个Query

          filters:
            - StripPrefix=1 # 截取掉断言路径的第一部分
management:
  endpoint:
    web:
      exposure:
        include: '*'
测试

测试链接:http://localhost:9966/nancy/hello
当不传id时,测试不通过:
在这里插入图片描述

传id以及value值时,测试通过:
在这里插入图片描述

四、断言-将请求按设定的权重进行分流

实现路由权重,需要参数 group 和weight(int);按照路由权重选择同一个分组中的路由。

涉及到要用权重分流的场景

案例、断言-WeightDemo

gateway的配置信息
该路由配置 约 80%的流量转发到服务 nacos-consumer ,约20%的流量转发给服务nacos-consumer-openFeign
路由属性Weight接收两个参数:groupweight(int),分流权重按组计算,在断言里配置权重路由配置如下:

主要配置信息

gateway的yaml文件配置如下:

 server:
  port: 9999
spring:
  application:
    name: gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: 172.18.101.197:80
    gateway:
      discovery:
        locator:
          enabled: false # 开启注册中心路由功能
      routes:
        # 配置流量分流权重
        - id: nacos-consumer-router
          uri: lb://nacos-consumer #路由到注册中心,服务为nacos-consumer的服务
          predicates:
            - Path=/testC/** # 路径匹配,则进行路由
            - Weight=group1, 2
          filters:
            - StripPrefix=1 # 截取掉断言路径的第一部分

        - id: nacos-consumer-openfeign
          uri: lb://nacos-consumer-openfeign #路由到注册中心,服务为nacos-consumer的服务
          predicates:
            - Path=/testC/** # 路径匹配,则进行路由
            - Weight=group1, 8
          filters:
            - StripPrefix=1 # 截取掉断言路径的第一部分
 
management:
  endpoint:
    web:
      exposure:
        include: '*'
 

9101和9102接口,分别为:
接口映射明不变,返回值为对应端口

	//9102
	static  AtomicInteger a1=new AtomicInteger(0);

    @GetMapping("/abTest")
    public String versionB() throws InterruptedException {
        log.info("端口9102 调用次数 " + a1.incrementAndGet());
        return "version_B--9102";
    }
   //9101
    private static AtomicInteger a = new AtomicInteger(0);

    @GetMapping("/abTest")
    @SentinelResource(value = "version_A")
    public String versionB() throws InterruptedException {
        log.info("端口9101 调用次数 " + a.incrementAndGet());
        return "version_A--9101";
    } 
测试

启动三个服务,注册中心可以看到服务均已注册成功:
在这里插入图片描述
测试链接:http://localhost:9999/testC/abTest
验证分流情况,预期结果:9101 约20%的流量,9102约80%的流量。
实际结果:
通过jmeter测试,总请求数量设定1000,从控制台可观测到结果:
在这里插入图片描述

在这里插入图片描述
可看出请求分流权重,实际结果跟预期相符。

http://www.dtcms.com/a/99859.html

相关文章:

  • Kafka 多线程开发消费者实例
  • 第四天 文件操作(文本/CSV/JSON) - 异常处理机制 - 练习:日志文件分析器
  • 【Python】基于 qwen_agent 构建 AI 绘画智能助手
  • Linux 文件存储和删除原理
  • Unity编辑器功能及拓展(2) —Gizmos编辑器绘制功能
  • Kafka消息丢失全解析!原因、预防与解决方案
  • 如何查看 SQL Server 的兼容性级别
  • 基于ruoyi快速开发平台搭建----超市仓库管理(修改记录1)
  • 《C++11:通过thread类编写C++多线程程序》
  • 编辑器场景视窗扩展
  • SpringBean模块(一)定义如何创建生命周期
  • 《C++Linux编程进阶:从0实现muduo 》-第6讲.C++死锁问题如何分析调试-原子操作,互斥量,条件变量的封装
  • 稻壳模板下载器(Windows):免费获取WPS稻壳模板的利器
  • Java中优先级队列的实现
  • 蓝桥杯备考------>双指针(滑动窗口)
  • 华为OD机试2025A卷 - 最大值(Java Python JS C++ C )
  • PyTorch 2.6.0没有对应的torch-sparse版本,不要下载pytorch最新版本,否则用不了图神经网络torch_geometric
  • vmware_unbantu刷新IP
  • EtherNet/IP转ProfiNet协议转换网关驱动西门子PLC与流量计的毫秒级压力同步控制
  • 洛谷题单1-P5706 【深基2.例8】再分肥宅水-python-流程图重构
  • MySQL单表查询、多表查询
  • linux实现rsync+sersync实时数据备份
  • Redis-快速入门
  • GPT Actions
  • 【硬件测试】基于FPGA的16QAM+帧同步系统开发与硬件片内测试,包含高斯信道,误码统计,可设置SNR
  • 【Find My全球市场观察:中国制造如何改写游戏规则?】
  • 游戏引擎学习第191天
  • 【Python】工作笔记:返回当月第一天、昨天;上月第一天、当天;全年节假日
  • 淘宝客户端动态化页面搭建
  • Linux课程学习一