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

springCloud/Alibaba常用中间件之GateWay网关

文章目录

  • SpringCloud:
    • 依赖版本补充
    • GateWay:网关
      • 三大核心之Router:路由
        • 1、导入基础依赖
        • 2、进行服务注册
        • 3、路由映射
        • 4、测试访问GateWay的端口是否可以访问
      • 三大核心之Predicate:断言
        • 配置文件
        • 自定义Predicate(断言)
      • 三大核心之Filter:过滤
        • 配置文件
        • 自定义全局过滤 —— 输出每一个路由所执行的时间
        • 自定义路由过滤器 —— 输出指定的路由所执行的时间、设置路由必填参数
          • 源码分析:自定义过滤器 —— apply()
          • 过滤链列表的构建:
          • 过滤器链的执行流程


SpringCloud:

微服务的中间件介绍与使用
微服务架构体系图:
在这里插入图片描述

依赖版本补充

下面所有代码中的依赖版本如下:

<properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><hutool.version>5.8.22</hutool.version><lombok.version>1.18.30</lombok.version><druid.version>1.2.18</druid.version><mybatis.springboot.version>3.0.3</mybatis.springboot.version><mysql.version>8.0.33</mysql.version><fastjson2.version>2.0.48</fastjson2.version><swagger3.version>2.2.0</swagger3.version><mapper.version>4.2.3</mapper.version><persistence-api.version>1.0.2</persistence-api.version><spring.boot.test.version>3.1.5</spring.boot.test.version><spring.boot.version>3.2.0</spring.boot.version><spring.cloud.version>2023.0.0</spring.cloud.version><spring.cloud.alibaba.version>2023.0.0.0-RC1</spring.cloud.alibaba.version><knife4j-openapi3.version>4.4.0</knife4j-openapi3.version>
</properties>

GateWay:网关

什么是网关网关 简单的理解就是在请求和服务之间加了一个 中间层
作用是
一、管控 路由的请求(反向代理、鉴权、流量控制、熔断、日志监控)
二、在每次路由中进行 增删内容
图形化展示网关位置:

在这里插入图片描述

工作原理
在这里插入图片描述

简单总结就是:路由转发+断言判断+执行过滤链列表

参考官网:https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway/how-it-works.html

三大核心之Router:路由

概念:路由是构建网管的基本模块,它有ID、目标URI、一系列断言和过滤器组成,如果断言为true则匹配该条路由

接下来直接开始配置一个基本的路由

1、导入基础依赖
<!--gateway依赖-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--服务注册发现consul discovery,网关也要注册进服务注册中心统一管控-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- 指标监控健康检查的actuator,网关是响应式编程删除掉spring-boot-starter-web dependency-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2、进行服务注册
server:port: 9567
spring:application:name: cloud-gatewaycloud:consul:port: 8500 #consul的端口号host: localhost #consul的网址discovery:service-name: ${spring.application.name} #配置服务名

启动类添加注册注解


@SpringBootApplication
@EnableDiscoveryClient/*服务组注册*/
public class Main9567 {public static void main(String[] args) {SpringApplication.run(Main9567.class, args);}
}

启动查看是否完成了服务注册
在这里插入图片描述

3、路由映射

这里可以先创建一个简单的业务[可以不需要数据库就返回一个值即可]做映射地址(别忘了要进行服务注册)
这里为了方便我就修改一下上面的业务的进行测试了。配置好测试业务之后,在路由服务的配置文件中进行配置:

server:port: 9567spring:application:name: cloud-gatewaycloud:consul:port: 8500 #consul的端口号host: localhost #consul的网址discovery:service-name: ${spring.application.name} #配置服务名gateway:routes:- id: gateway_router_1  #路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名#配置地址方法一(不推荐):#          uri: localhost:8001 #填写业务服务的地址和端口号(缺点:灵活性差)#方法二(推荐):动态路由uri: lb://cloud-payment-service #填写业务服务名(优点:可动态的配置路由,lb:可以支持负载均衡)predicates: # 配置一个简单的断言,以便于演示。也就是访问此路由的条件- Path=/pay/gateway/get/** #满足此路由的才可以访问,**:通配符- id: gateway_router_2uri: lb://cloud-payment-servicepredicates:- Path=/pay/gateway/info/**
4、测试访问GateWay的端口是否可以访问

在这里插入图片描述

访问成功,说明映射成功了!

这里可以也试一下当有多个服务(yourServerName),下使用lb://yourServerName是否有负载均衡的效果

三大核心之Predicate:断言

概念:开发人员可以匹配HTTP请求中的所有内容,如果请求与断言相匹配则进行路由

配置文件
    gateway:routes:- id: gateway_router_1  #路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名#配置地址方法一(不推荐):#          uri: localhost:8001 #填写业务服务的地址和端口号(缺点:灵活性差)#方法二(推荐):动态路由uri: lb://cloud-payment-service #填写业务服务名(优点:可动态的配置路由,lb:可以支持负载均衡)predicates: # 配置一个简单的断言,以便于演示。也就是访问此路由的条件- Path=/pay/gateway/get/** #满足此路由的才可以访问,**:通配符- id: gateway_router_2uri: lb://cloud-payment-servicepredicates:- Path=/pay/gateway/get/**              # 断言,路径相匹配的进行路由- After=2025-04-20T16:04:22.672173200+08:00[Asia/Shanghai]   #配置指定的时间之后才开启此路由- Before=2025-04-20T16:08:13.979939200+08:00[Asia/Shanghai]   #与after相反,没有达到此时间之后都可以访问,过了之后便会直接关闭- Between=2025-04-20T16:09:38.676463500+08:00[Asia/Shanghai],2025-04-20T16:11:38.676463500+08:00[Asia/Shanghai] #区间- Cookie=phone,^1(3[0-9]|4[57]|5[0-35-9]|7[0678]|8[0-9])\d{8}$    #根据cookie参数进行验证,第一个是key值,第二个是规定value值正则- Header=X-Request-Id, \d+    #根据请求头的参数名和值进行判断,第一个值是name,第二个值是正则表达式- Host=**.chyb.com,**.chyb.org  #根据Host这个参数进行模糊查询,**:通配符- Query=num, \d+ #必须要有num这个参数,且值为整数- RemoteAddr=192.168.235.0/24 #根据请求人的ip进行拦截,/24:是指前面的24位是不可以变的,24:前面的192.168.43是不可以变得,注意:这里请求的时候不要在使用localhost而是要输入自己的IP地址- Method=GET,POST #按照请求方式进行匹配

这里就相当于API的调用一样没有什么好说的,不清楚的可以直接参考官方文档:https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway/request-predicates-factories.html
中文官网:https://springdoc.cn/spring-cloud-gateway/#gateway-request-predicates-factories
这里在单独将一个知识点领出来说:快捷方式的配置(常用)完全展开的参数 语法如下:

# 快捷方式的配置
- Cookie=mycookie,mycookievalue
#完全展开的参数:完全展开的参数看起来更像标准的yaml配置,有名称/值对。一般来说,会有一个 name key和一个 args key。args key是一个键值对的映射,用于配置谓词或过滤器。
- name: Cookieargs:name: mycookieregexp: mycookievalue
自定义Predicate(断言)

创建 ~RoutePredicateFactory 类,其代码如下:


@Component /*注入Spring容器中*/
/*注意命名规范:~~~RoutePredicateFactory*/
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {public MyRoutePredicateFactory() {super(MyRoutePredicateFactory.Config.class);}@Validatedpublic static class Config {@Setter@Getter@NotEmptyprivate String userType; //钻、金、银等用户等级}/*** 写逻辑:根据userType进行判断是否可以访问此路由* @param config* @return*/@Overridepublic Predicate<ServerWebExchange> apply(MyRoutePredicateFactory.Config config) {return new Predicate<ServerWebExchange>() {@Overridepublic boolean test(ServerWebExchange serverWebExchange) {//检查request的参数里面,userType是否为指定的值,符合配置就通过String userType = serverWebExchange.getRequest().getQueryParams().getFirst("userType");if (userType == null) return false;//如果说参数存在,就和config的数据进行比较if (userType.equals(config.getUserType())) {return true;}return false;}};}/*** 用来支持断言的快捷方式* @return*/@Overridepublic List<String> shortcutFieldOrder() {return Collections.singletonList("userType");}
}

配置文件的设置

#....
predicates:#这里的"My"是根据你类名有关系,当遵守命名规范:~RoutePredicateFactory,则默认的名字就是:~- My=diamond  #当参数userType的值等于diamond才可以访问此路由

三大核心之Filter:过滤

概念:指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求路由之前或之后对请求进行修改
过滤器类型分为:

  1. 全局默认过滤器 (Global Filters):每一个路由都要执行的过滤器
  2. 单一内置过滤器 (GateWayFilter),“又称路由过滤器”:指定某一个路由执行的过滤器
配置文件
          filters:#             RequestHeader的增删改- AddRequestHeader=chyb-name, chybName1 #添加一个请求头(chyb-name)值为:chybName1- AddRequestHeader=chyb-name2, chybName2- RemoveRequestHeader=chyb-name  #删除一个请求头(user-agent)- SetRequestHeader=chyb-name2, chybName3 #修改某一个请求头(chyb-name2)的值为chybName3,若是没哟此请求头,则直接会自动添加#             RequestParameter请求参数的增删- AddRequestParameter=param1, 2983 #增加参数- RemoveRequestParameter=param2   #删除参数#             ResponseHeader 响应头的增删改- AddResponseHeader=chybName, chyb1 #创建一个响应头(chybName)值为:chyb1- SetResponseHeader=date, 2006-02-09 #设置date响应头的值为:2006-02-09- RemoveResponseHeader=Content-Type #删除Content-Type(接受类型)#             前缀、路径、相关的配置- PrefixPath=/pay   #设置访问路径的前缀- SetPath=/pay/gateway/{param}   #设置访问路径,{~}为占位符- RedirectTo=301, https://baidu.com   #重定向到https://baidu.com,状态吗为302

参考官网:https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway/gatewayfilter-factories.html

中文官网:https://springdoc.cn/spring-cloud-gateway/#gatewayfilter-%E5%B7%A5%E5%8E%82

自定义全局过滤 —— 输出每一个路由所执行的时间

1、创建一个~~GlobalFilter,并实现自定义过滤器所需的接口:GlobalFilter, Ordered

/*注入到Spring容器中,之后会将所有注入到容器中的过滤器进行合并,形成过滤器列表*/
@Component
@Slf4j
/*这里是自定配置全局过滤器,就是每一个路由都会去执行的*/
public class MyGlobalFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {return null;}/*** 设置执行接口进行排序,返回值越小越靠前* @return*/@Overridepublic int getOrder() {return 0;}
}

2、在filter方法下写执行逻辑,实现:输出每一个路由所执行的时间


public static final String BEGIN_VISIT_TIME = "BEGIN_VISIT_TIME";/*初始化方法执行的开始时间*//***用来接受响应请求报文,以及控制放行操作(这里有点像将拦截器中的preHandle[访问前拦截方法]和postHandle[访问后拦截方法]结合到一起了)* @param exchange :类似于Server,它里面封装了三个属性:*                 ServerHttpResponse、ServerHttpRequest:这两个属性存储着:请求/响应的报文,所以可以通过exchange这个参数获取到这些属性*                 Map<String, Object>:这属性就是我们要进行额外的添加对象就可以添加到这里,运用的方法就直接.pus即可* @param chain : 这个属性可以控制过滤器的放行操作* @return 这里返回的类型是Mono这个类型是在SpringBoot响应式编程中所引出的类,适用于高并发和高吞吐量场景(在资源有限的情况下提高系统的吞吐量和伸缩性【并非提高性能】)*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {System.out.println("=====" + exchange.getAttributes().get(BEGIN_VISIT_TIME) + "=====");exchange.getAttributes().put(BEGIN_VISIT_TIME, System.currentTimeMillis());System.out.println("------" + exchange.getAttributes().get(BEGIN_VISIT_TIME) + "-----");/*** 这里的chain.filter(exchange)是放行操作,而.then()是任务串联(在 Mono完成后触发新任务,但不依赖前一个任务的输出结果。)*/return chain.filter(exchange).then(Mono.fromRunnable(() -> {Long beginTime = exchange.getAttribute(BEGIN_VISIT_TIME);URI uri = exchange.getRequest().getURI();if (beginTime != null) {log.info("访问接口主机:{}", uri.getHost());log.info("访问接口端口号:{}", uri.getPort());log.info("放文件接口URL:{}", uri.getPath());log.info("访问接口的URL参数:{}", uri.getQuery());log.info("访问时长:{}ms", (System.currentTimeMillis() - beginTime));log.info("============================================");System.out.println();}}));
}

这里因为是全局过滤器,所以并不需要进行单独配置yml。

3、测试(访问任意路由查看日志是否输出)
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

自定义路由过滤器 —— 输出指定的路由所执行的时间、设置路由必填参数

1、创建自定义路由过滤器类,注意类名~~GatewayFilterFactory
案例一:日志输出指定的路由所执行的时间

/*注入到Spring容器中,之后会将所有注入到容器中的过滤器进行合并,形成过滤器列表*/
@Component
@Slf4j
/*自定义路由过滤器,指定某一个路由执行的过滤器,无参数的写法(只需要编写apply方法即可,注意config的类型)*/
/*注意命名规范:~GatewayFilterFactory*/
public class MyGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> {static final String BEGIN_TIME = "begin_time";@Overridepublic GatewayFilter apply(Object config) {System.out.println("进入了自定义网关过滤器MyGatewayFilterFactory,status:" + config);return new GatewayFilter() {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {exchange.getAttributes().put(BEGIN_TIME, System.currentTimeMillis());return chain.filter(exchange).then(Mono.fromRunnable(() -> {Long beginTime = exchange.getAttribute(BEGIN_TIME);URI uri = exchange.getRequest().getURI();if (beginTime != null) {log.info("------------------我是路由过滤器----------------------");log.info("访问接口主机:{}", uri.getHost());log.info("访问接口端口号:{}", uri.getPort());log.info("放文件接口URL:{}", uri.getPath());log.info("访问接口的URL参数:{}", uri.getQuery());log.info("访问时长:{}ms", (System.currentTimeMillis() - beginTime));log.info("============================================");System.out.println();}}));}};}
}

案例二:设置路由必填参数


@Component
/*定义路由有参过滤器*/
public class MustQueryGatewayFilterFactory extends AbstractGatewayFilterFactory<MustQueryGatewayFilterFactory.Config> {/*初始化*/public MustQueryGatewayFilterFactory() {super(MustQueryGatewayFilterFactory.Config.class);}/*用来配置快捷访问方式的传参的位置*/@Overridepublic List<String> shortcutFieldOrder() {return Arrays.asList("status");}/*定义一个内部类用来存放接受的参数,同时也是继承AbstractGatewayFilterFactory类的泛型*/public static class Config {@Getter@Setterprivate String status;//设定一个状态值/标志位,它等于多少,匹配和才可以访问}/*** 写过滤器逻辑的方法* @param config 传递参数值* @return*/@Overridepublic GatewayFilter apply(MustQueryGatewayFilterFactory.Config config) {return new GatewayFilter() {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request = exchange.getRequest();/*动态的将配置的参数设为传必传参数的name*/System.out.println("进入了自定义网关过滤器MyGatewayFilterFactory,status:" + config.getStatus());if (request.getQueryParams().containsKey(config.getStatus())) {return chain.filter(exchange);} else {exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);return exchange.getResponse().setComplete();}}};}
}
//单一内置过滤器GatewayFilter

2、配置yml
在指定的路由上添加路由过滤器

server:port: 9567
spring:application:name: cloud-gatewaycloud:consul:port: 8500 #consul的端口号host: localhost #consul的网址discovery:service-name: ${spring.application.name} #配置服务名gateway:routes:- id: gateway_router_1uri: lb://cloud-payment-servicepredicates:- Path=/pay/gateway/info/**              # 断言,路径相匹配的进行路由filters:- My #配置日志输出指定的路由所执行的时间的路由过滤器- id: gateway_router_2uri: lb://cloud-payment-servicepredicates:- Path=/pay/gateway/get/**filters:- MustQuery=chyb #配置必传参数名,否则访问不了

测试

案例一:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

案例二:

在这里插入图片描述

源码分析:自定义过滤器 —— apply()

我们以这段代码为例:


@Override
public GatewayFilter apply(Object config) {System.out.println("进入了自定义网关过滤器MyGatewayFilterFactory,status:" + config);return new GatewayFilter() {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {exchange.getAttributes().put(BEGIN_TIME, System.currentTimeMillis());return chain.filter(exchange).then(Mono.fromRunnable(() -> {
//                .....}));}};
}

这里我们把重心放在:public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {}

这里的第一个参数exchange:里面封装了三个参数(上面自定义全局过滤器注释有,所以不多讲 getRequest、getResponse、getAttributes)

第二个参数chain:主要是用来进行放行操作的,而这里是怎么放行的我们就从过滤链列表构建过滤器链的执行流程

过滤链列表的构建:

过滤链列表由来:全局过滤器列表路由过滤器列表 动态合并而成

  1. 全局过滤器列表

    是根据Spring容器扫描所有的 GlobalFilter 的实现类,
    通过 @Order 注解或 Ordered 接口的 getOrder()
    方法对全局过滤器进行排序,形成全局过滤器列表。从而形成的一个列表。

  2. 路由过滤器列表

    从配置文件(如 YAML)或代码中解析路由规则,提取每个路由的 filters 列表。
    这里还有一个点要注意:配置文件中的过滤器名称(如 AddRequestHeader),会默认转化为 GatewayFilter实例
    (也就是我们自定义的路由过滤器类),
    然后根据所有的 GatewayFilter实例添加到 路由过滤器列表

  3. 动态合并而成:

    当请求到达时,网关根据当前请求匹配的路由,将 全局过滤器列表路由过滤器列表 合并。

    路由过滤器按配置顺序追加到全局过滤器之后,便形成了过滤链。排序规则[全局过滤器按 @Order 排序(值越小优先级越高)]

    源码示例(合并):FilteringWebHandler类中的handle()

public Mono<Void> handle(ServerWebExchange exchange) {// 1. 获取全局过滤器和路由过滤器List<GatewayFilter> globalFilters = this.globalFilters;List<GatewayFilter> routeFilters = route.getFilters();// 2. 合并过滤器列表List<GatewayFilter> combined = new ArrayList<>(globalFilters);combined.addAll(routeFilters);// 3. 排序(全局过滤器按 Order,路由过滤器按配置顺序)AnnotationAwareOrderComparator.sort(combined);// 4. 创建过滤器链return new DefaultGatewayFilterChain(combined).filter(exchange);
}

这就是形成过滤器列表的大致过程。

过滤器链的执行流程
  1. 链式调用模型:
    1. 责任链模式:通过 DefaultGatewayFilterChain (
      这个类是FilteringWebHandler类的内部类,要想找的话可以直接搜索这个类) 递归调用每个过滤器,直到所有过滤器执行完毕。
    2. 响应式编程:使用 Mono 和 .then() 实现异步非阻塞执行。(这里不懂的话可以看一下SpringBoot的响应式编程)
  1. 核心代码展示:
    这里可以找到 chain.filter(exchange)【我们自定义过滤器中所返回的那个方法】的实现类 FilteringWebHandler
    找到内部类 DefaultGatewayFilterChain

    核心代码如下:
public class DefaultGatewayFilterChain implements GatewayFilterChain {private final List<GatewayFilter> filters;private final int index; // 当前执行过滤器的索引@Overridepublic Mono<Void> filter(ServerWebExchange exchange) {return Mono.defer(() -> {if (index < filters.size()) {// 1. 获取当前过滤器GatewayFilter filter = filters.get(index);// 2. 创建下一个链(index+1)GatewayFilterChain nextChain = new DefaultGatewayFilterChain(this, index + 1);// 3. 执行当前过滤器,传递下一个链return filter.filter(exchange, nextChain);} else {// 4. 所有过滤器执行完毕return Mono.empty();}});}
}
  1. 执行顺序示例
    假设合并后的过滤器列表为:[GlobalFilterA, GlobalFilterB, RouteFilter1, RouteFilter2]

执行流程:

  1. GlobalFilterA 的前置逻辑 → 调用 chain.filter()
  2. GlobalFilterB 的前置逻辑 → 调用 chain.filter()
  3. RouteFilter1 的逻辑 → 调用 chain.filter()
  4. RouteFilter2 的逻辑 → 调用 chain.filter()
  5. 路由到目标服务 → 返回响应
  6. RouteFilter2 的后置逻辑(通过 .then())
  7. RouteFilter1 的后置逻辑
  8. GlobalFilterB 的后置逻辑
  9. GlobalFilterA 的后置逻辑。
    这里可以自己打几个断点到DefaultGatewayFilterChain类中一步一步的查看源码查看,会更清晰一些

上述大部分代码以上传到gitee:https://gitee.com/banhuayue/springCloud-Alibaba-code.git

笔记参考来自尚硅谷

http://www.xdnf.cn/news/4828.html

相关文章:

  • 大型语言模型在网络安全领域的应用综述
  • 【WEB3】区块链、隐私计算、AI和Web3.0——数据民主化(1)
  • Python爬虫(21)Python爬虫进阶:Selenium自动化处理动态页面实战解析
  • RabbitMQ--基础篇
  • Android Studio 模拟器配置方案
  • 跨平台移动开发框架React Native和Flutter性能对比
  • 每周靶点分享:Angptl3、IgE、ADAM9及文献分享:抗体的多样性和特异性以及结构的新见解
  • 从代码学习深度学习 - 单发多框检测(SSD)PyTorch版
  • Comfyui 与 SDwebui
  • C++内存管理与模板初阶详解:从原理到实践
  • Java详解LeetCode 热题 100(13):LeetCode 53:最大子数组和(Maximum Subarray)详解
  • Android学习总结之算法篇八(二叉树和数组)
  • 10. CSS通配符与选择器权重深度解析:以《悯农》古诗为例
  • 比较Facebook与其他社交平台的隐私保护策略
  • RSS 2025|斯坦福提出「统一视频行动模型UVA」:实现机器人高精度动作推理
  • 机器视觉的手机FPC油墨丝印应用
  • 在k8s中,如何实现服务的访问,k8s的ip是变化的,怎么保证能访问到我的服务
  • 数据结构-非线性结构-二叉树
  • G口大带宽服务器线路怎么选
  • 根据窗口大小自动调整页面缩放比例,并保持居中显示
  • Python程序,输入IP,扫描该IP哪些端口对外是开放的,输出端口列表
  • Vue生命周期脚手架工程Element-UI
  • 经济体制1
  • http重新为https
  • 基于FPGA婴儿安全监护系统(蓝牙小程序监测)
  • 2025年渗透测试面试题总结-某服面试经验分享(附回答)(题目+回答)
  • R 语言机器学习:为遥感数据处理开启新视角
  • 二元随机响应(Binary Randomized Response, RR)的翻转概率
  • flink超时未揽收单量统计
  • 【AI提示词】马斯洛需求分析专家