工程解释:
性能测试是针对系统的性能指标,建⽴性能测试模型,制定性能测试⽅案,制定监控策略,在场景条件之下执⾏性能场景,分析判断性能瓶颈并调优,最终得出性能结果来评估系统的性能指标是否满⾜既定值。
性能测试的价值
分类:
1. 性能验证:针对给定的指标,只做性能验证
2. 性能测试:针对给定的系统做全面的性能测试,可以得到系
统的最大容量,但不涉及到调优 –-旧系统保证系统不衰减
3. 性能测试+性能调优:针对给定的系统做全面的性能测试,
同时将系统调整到“最优”状态
意义:
1.验证系统上线之后是否可以稳定运行
2.给出开发和运维人员提出线上的配置建议
3.在满足业务要求的前提下,可以节省资源
200 X 2W = 400W
60 X 2W = 120W
1.2 什么是性能要求
1.2.1 我的系统需要测试多大的并发?
注册用户数–>在线用户数–>活跃用户数
结论:无固定计算关系,那就只能用平均
所谓的方法一:
在线用户数 = 注册用户数 * (5%-20%)
并发用户数 = 在线用户数 * 30%
举例: 开发统计出数据库中总共有1000人注册过
1000 * 0.2 * 0.3 = 60 也就是说有60人每秒同时访问
并发度
并发度为注册用户数的 万分之5 - 万分之6
并发度为在线用户数的 5%
何为并发度:
结论:毫无依据,非要信,就拉上一个专家甩锅
所谓的方法二:
可以从系统日志中拿到,日活跃用户(可以定义为每天最少使用一次)400
并发 = 400 * 30%
1.2.2 获取到真实的用户访问数据
以业务(单个接口或单个业务场景)为单位,获取一个单位时间内的访问次数。
场景一: 8000000/月
266667/天 11111//小时 185/分钟 3/秒
场景二: 月末最后一天交易量最大为 300000/天
12500/小时 208/分钟 3.5/秒
场景三: 当天下午16:00交易量最大 20000/小时
333/分钟 5.6/秒
场景四: 当天下午16:23 分,交易量最大 500/分钟
8.3/秒
结论:交易有实时性,分布不规律。如果平均,计算结果一定会小于实际峰值
关键点一: 尽可能拉长采样周期,找到交易峰值日--峰值小时---峰值分钟(一般无法做到)
关键点二: 按照一定比列模拟峰值
假设:交易峰值日当天的交易总额为:1000000(100万)
场景一:各个小时交易量基本均等
100%的交易发生在100%的时间内
1000000/24*60*60 = 11.6/秒
场景二:我的系统凌晨1点 2点 3点 访问量基本可以忽略,剩下时间内差异不大
100%的交易发生在87.5%的时间内
1000000/24*60*60*0.875 = 13.3/秒
场景三:我的系统 9:00 10:00 15:00 16:00 17:00 五个小时的交易量占到总数的80%
80%的交易发生在20%的时间内
1000000*0.8/24*60*60*0.2 = 46.3/秒
场景四:我的系统 16:00 17:00 两个小时的交易量占到总数的90%
1000000*0.9/24*60*60*0.08 = 130/秒
如果再对小时内数据做分布统计,并发还有可能变大
结论:所谓的 28 19 和并发度一样,只是无数据支撑时候的拍脑袋参考,既然拍了你选择多少结果都一样
练习:
单交易练习:
1.2.3 如何设计性能场景
对于每一个接口都会有访问计数,这是目前业内比较常见的,也是衡量接口访问能力最准确的指标之一。一般大公司会自己开发相应的监控工具,发展中的公司也会使用一些开源或者商业工具进行监控。有了工具之后我们应该如何去统计这些数据呢?或者说如何根据这些数据设计性能测试场景呢?
1.首先我们要有长时间的业务统计数据。比如,取近一个月的数据,这个数据越长越好,最关键的是要覆盖足够的业务场景日。
实例一:某次双11大促压测
现在很多电商,如京东的“双十一”活动可能从 11 月 1 日就开始了,其中穿插了一些品类活动和推送,所以有流量冲高的情况也是比较正常的。因此,对于上述这个场景一般会对最高峰和次高峰都进行分析。
实例二:(请求次数已按100比例缩小,请只观察走势)
针对产品查询业务峰值日:10-26,查询全天数据:
登录: 901800 31.8%
产品查询:1184100 41.7%
根据二八原则:11841000.8/240.26060 = 68.5
优惠码兑换查询:751200 26.5%
2.针对于某个业务场景日,查看详细按小时的统计信息。
目的是确认各个业务按小时的访问量
以诚品汇项目为例:选取 产品查询业务峰值日:10-26全天数据
以小时为单位,除去凌晨业务量较低的时间点。
16:00-16:59 详细数据:
交易总量:633400
登录:178500 28.2% 49.6 TPS
产品查询:352000 55.6% 97.8 TPS
优惠码兑换查询:102900 16.2% 28.6 TPS
总结:获取以下场景的 交易数以及各个业务比例分配
场景一:交易峰值日(10-28)交易峰值小时
场景二:交易峰值日(10-28)每个核心业务的峰值小时
场景三:登录业务峰值日(10-25) 核心业务峰值小时
场景四:产品查询业务峰值日(10-26) 核心业务峰值小时
场景五:优惠码兑换业务峰值日(10-27) 核心业务峰值小时
*场景六:普通交易日(10-31) 交易峰值小时
1.2.4 如何去评价我的系统所提供的服务
性能指标
如何正确理解TPS
什么是并发?指同一时间节点发生的事情
如果你关注的只是对数据库的压力,QPS可以代表数据库的承压能力。但是一个用户行为可能包含多个Q操作,也可能没有Q操作。
总之:RPS、QPS都是性能测试过程中,每个具体基准测试场景下可以使用的指标,在当前场景可以代表吞吐量。但不管是R还是Q都可以被称之为事务,那么我们不妨统一使用TPS这个指标。
• 接⼝级脚本:
——事务start(接⼝1)
接⼝1脚本
——事务end(接⼝1)
——事务start(接⼝2)
接⼝2脚本
——事务end(接⼝2)
——事务start(接⼝3)
接⼝3脚本
——事务end(接⼝3)
• 业务级接⼝层脚本:
注:就是⽤接⼝拼接出⼀个完整的业务流。
——事务start(业务A)
接⼝1脚本 - 接⼝2(同步调⽤)
接⼝1脚本 - 接⼝3(异步调⽤)
——事务end(业务A)
• ⽤户级脚本
——事务start(业务A)
点击0 - 接⼝1脚本 - 接⼝2(同步调⽤)
点击0 - 接⼝1脚本 - 接⼝3(异步调⽤)
——事务end(业务A)
如何理解响应时间 RT
既然对事务的定义不同,如何理解响应时间?
如何根据响应时间计算TPS以及线程数
虚拟用户:性能工具中的线程数
a.虚拟用户不代表UV、PV,更不等价于真实用户,它只是性
能测试工具实现并发的一种手段。
b.线程数 不等于 并发 更不等于 TPS
c.一个线程一秒内可以发送几个请求,取决于服务的响应时间以及压测人员的配置。
计算方式一:
Throughput = (number of requests) / (total time)
计算方式二:
目标TPS = 线程数/平均响应时间
并发用户数、并发线程数 与 TPS的关系
假如 事务的平均响应时间是:200ms,要实现1000tps,需要几个用户(虚拟线程)?
1000 = X / 0.2 X = 200
更简单的计算:发一个请求0.2s,一秒钟一个用户就可以发5个请求,只要有200个用户每秒不停这样发送,就是1000tps。
注意:这只是估算。RT是变化的所以TPS也一定是变化的,但是这个初始估算的线程数可以作为你梯度加压的边界参考。
错误率
这个指标也是比较重要的,错误率的计算方式是在统计时间范围内不符合返回期望的请求数除以总共的请求数。在测试中,这一指标不符合期望的话一般体现在对结果的校验上,一般会分为三个层面进行校验:
状态码的校验,这在性能工具中不需要特别设置,如 4XX、5XX 这样的状态码会直接报错;
业务层面的校验,为了保证业务的基本准确性,会通过返回的数据包进行校验;
数据库校验, 相对于业务测试,性能测试的每一次请求不会都做数据库校验,这样会影响性能测试结果,可以在一轮性能测试之后去统计落库数据的数量和状态是否正常。
以测试登录为例:
如果用户名和密码不匹配会返回一段错误报文,不需要走正确流程中的校验逻辑;
如果用户名和密码匹配,一般会有多层校验。
这二者存在较大的差别,在实际压测过程中也存在业务没有校验,但已经发生错误的情况,这是不能及时发现的。
资源利用率指标
我们来选取几个真实的性能测试报告:
实例1
实例2
实例3
合理化建议: 1. 每个接口需要有响应时间RT指标
2. 每个业务需要有TPS、响应时间RT和错误率指标
3. 每个性能场景需要有TPS和错误率指标
4. 每个单独业务和性能场景下需要有对应的资源利
用率指标
性能测试场景分类以及意义
混乱的概念:
我们换一种角度,从性能测试的目标出发。整理出如下场景:
准入测试、单交易基准、单交易负载(单交易容量)、多交易混合容量测试
一、单交易基准场景
基准场景是指单线程或者少量线程(一般在 5 个线程以下)对单接口进行测试,然后将测试结果作为基准数据,在系统调优或者评估的过程中,通过运行相同的业务接口比较测试结果,为系统的优化以及后续测试流程提供决策数据。
有人觉得基准测试并不是在高并发下进行的,不算是性能测试,但这其实是性能测试中重要的基础步骤,它有以下作用:
验证测试脚本及测试参数的正确性,同时也可以验证脚本数据是否能够支持重复性测试等;
通过少量线程访问系统获取结果数据,作为对比参考基准;
主要目的是获取单个交易在无压力的情况下的基准响应时间及环境资源使用情况,作为其他场景的参考依据
根据测试结果,初步判断可能成为系统瓶颈的场景,并决定是否进行后续的测试;
基准场景的结果被一部分公司作为上线的基线指标,不达到要求是不允许上线的,这样的场景也经常被固化成自动化的脚本定时触发和巡检。
什么是性能预热测试?
预热测试相当于升级版的基准测试。主要是已经使用的系统,在更新迭代之后使用原有普通交易日每个交易的均值TPS,优先进行一轮压测。目的主要是检查性能是否有严重衰减,是否有报错,是否有进一步进行后续压测的必要。
二、单交易(接口)负载场景
单接口负载场景就是通过模拟多线程对单接口进行负载测试。具体做法是:
1.根据业务模型中该交易(接口)的目标TPS和基准测试中获得的静态(低压力)下的平均RT估算线程数的取值范围
2.根据线程的取值范围,按照梯度加压的方式,每一组线程数运行 一段时间,然后获取事务响应时间、TPS、报错率,监测测试系统的各服务器资源使用情况(CPU、内存、磁盘、网络等),把具体数据记录之后再开始跑下一个线程数。每一组线程数级别会有对应的 TPS,直到你找到需要的数据,比如 TPS 的”拐点"。
3.比如接口RT均值为500ms,目标TPS 1000分别运行 100 线程、200 线程、300线程、400线程、500线程等,一般相同线程数运行 10~15 min,然后获取事务响应时间、TPS、报错率。如下图所示,横坐标是线程数,纵坐标是 TPS,线程数增加到 400 时出现了拐点。
我们需要在单交易容量中获取到的信息:
1.验证该交易知否支持性能指标中的目最大TPS
2.如果上一步不支持,它目前的最大TPS是多少
3.如果超过目标最大TPS,是否有必要继续获取它的最大容量(TPS)
4.响应时间开始快速递增的点在哪里—最优响应时间
5.最优响应时间对应的TPS是多少
6.最大TPS或目标TPS对应的响应时间是多少,业务是否可以接受
一点建议:
关于三种曲线的说明:
我们在测试中需要重点关注三个曲线的增长关系:线程组变化、TPS变化、RT变化。
你应该见到这张图:
可以表示大体的走势 解释一些概念。但是不够准确
1.很多系统初始压测时,响应时间有明显的回落趋势(因为有初始资源创建的情况发生)。
2.大部分情况下响应时间不会出现陡增,更可能会提前增长。
3.有的控制较好的系统不会出现tps下降,到达瓶颈后会维持tps,或者由于响应时间本身较短,看不到tps明显的下降。
4.最优并发数通常不可信,谨慎起见应该提前。
最大并发数这个点,要比图中标注的第二条竖线提前
5.用户增长了不代表压力一定会线性增加,资源也不一定就持续往上涨。
我们来给出一张性能测试人员期待的理想图:
蓝色为tps曲线,橙色为响应时间曲线
A:最优响应时间
B:业务指标点
C:最大TPS下的响应时间
D:系统可以接受的最大响应时间,系统资源利用率最大化
E:最大响应时间,错误(超时)之前的最大时间
(三)、多交易混合容量测试–混合场景负载测试
混合场景是性能测试中最重要的场景之一,这个场景是为了最大程度模拟用户真实的操作。真实的线上操作不只有单接口的操作,一定是多种业务同时在进行,比如张三在浏览商品,李四在添加购物车等。
所以混合场景测试会将多个接口按照实际大促时候的比例混合起来,然后增加线程数找出多个接口 TPS 的和对应的峰值。这个比例也是混合场景的关键,性能指标确定的环节中已经较为详细地阐述了制定比例的方法。加用户运行的基本策略可以参考上文的单接口负载测试。混合场景执行除了要观察总的 TPS,还有一个非常关键的因素就是如何控制接口之间的调用比例,使其不能偏离预期。比如利用Jmeter的吞吐量控制器。
(四)稳定性性能测试
性能测试中的稳定性测试是通过给系统加载一定压力的情况下,运行较长一段时间(8-24小时),验证系统是否稳定。通常是采用典型混合场景,查看系统运行指数是否平稳。 是否会出现TPS有较大波动、有错误和异常、内存溢出等。
1.核心就是时长。在长时间的运行下,观察系统性能表现,分析并且调优的过程。
2.除去有些系统会随着时间变长,自然衰减。大部分系统的时长,可以转化为交易量的累计(总事务数)。
例如:业务 + 运维部门联合给出了一个指标,那就是系统要稳定运行一周,支持 2000 万业务量。那么假如核心业务容量 TPS 能达到 3800。所以稳定性场景时间应该是:20000000/3800 = 1.46 小时。
3.在稳定性测试场景中关键点是:保持TPS的稳定。
4.究竟以多大的TPS去执行稳定性测试呢?交易峰值混合容量?
稳定性测试负载压力可以采用系统最大处理能力的70%或80%,或混合场景中的某个压力值;
(五)异常性能测试
性能测试也是存在异常测试的,顾名思义就是在系统异常的情况下看系统的处理能力或者是通过处理后的恢复能力是如何的。
比如在架构的高可用方面,遇到服务的上下线、数据库的主从切换等这些情况的时延是多少、处理能力能不能达到预期标准。另外在目前的电商应用架构中,大促遇到紧急情况经常需要限流和熔断。
限流就是控制单位时间内的请求量,比如说早晚高峰坐地铁,很多入口都会放隔离带,降低乘客流动速度,这就是一种限流方式。
熔断就比较直接了,当判断到调用的依赖服务报错到达一定数量后,直接返回一个既定的数据,将不再访问该服务。就像家中的保险丝一样,到达一定条件后,会自行断电,以保障电路安全。所以我们也会测试触发限流和熔断所设置的阈值,并观察在触发后的系统表现是如何的。主要是分阶段分批次熔断各个类型的服务,查询TPS波动以及恢复情况。
一、Jmeter基本使用
2.1安装与配置
2.1.1 安装
官方下载地址: http://jmeter.apache.org/download_jmeter.cgi
前提条件:安装JDK1.8+ 配置好java相关环境变量
windows:
1. 下载 Binaries zip 包
2. 解压到某个路劲
3. 在环境变量中新增 环境变量 JMETER_HOME,变量值为
JMeter解压的路径
4. 运行jmeter.bat
Mac/Linux:
1. 下载 Binaries tgz 包
2. 解压到某个路劲
3. 进入到bin目录下,通过sh jmeter命令来启动Jmeter
2.1.2 运行原理
JMeter以创建多个线程的方式来模拟多个用户执行操作,一个线程代表一个虚拟用户。当JMeter执行测试时,产生多个线程向被测系统发送请求,生成负载。
**补充知识:进程、线程、协程
1.操作系统是多任务的,多于现在的多核CPU一定程度上可以做到真正的任务并行,但是哪怕你有16核cpu,(说明一下物理核 逻辑核 超线程),依然避免不了出现一个cpu还需要并行多个任务。
2.操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换到任务2,任务2执行0.01秒,再切换到任务3,执行0.01秒……这样反复执行下去。表面上看,每个任务都是交替执行的,但是,由于CPU的执行速度实在是太快了,我们感觉就像所有任务都在同时执行一样。
3.对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程,打开一个Word就启动了一个Word进程。
4.有些进程还不止同时干一件事,比如Word,它可以同时进行打字、拼写检查、打印等事情。在一个进程内部,要同时干多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”称为线程(Thread)
5.我们一般认为线程就是不可再拆分的单元。但是线程却可以中断。
如果线程中断了,就可以模拟进程做的事情,也就是同一线程再次拆分成多个子任务交替执行,这就是协程。
6.线程的切换与调度是需要CPU完成的,但是可以有效利用上多核。
协程的调度CPU是不参与的,协程之间切换不需要切换线程。
因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。
2.1.3 目录结构
bin目录
jmeter.bat windows的启动文件
jmeter.log jmeter运行日志文件
jmeter.sh linux的启动文件
jmeter.properties 系统配置文件
jmeter-server.bat windows分布式服务器启动文件
jmeters-server linux分布式服务器启动文件
docs目录 -- 离线api文档
入口:docs\api下的index.html
extras目录 -- 扩展插件目录
lib目录 -- jar包存放目录
所用到的插件目录,里面均为jar包。jmeter会自动在jmeter_HOME/lib和ext目录下寻找需要的类,lib下存放JMeter所依赖的外部jar,如:httpclient.jar、httpcore.jar、httpmime.jar等等。
其中lib\ext目录下存放有Jmeter依赖的核心jar包,JMeter插件包也在此目录下。
Printable_docs目录 – 用户使用手册
修改jmeter.properties几个配置:
2.2 性能测试脚本开发
基本构成单元
测试计划(只有一个) — 线程组(至少一个) — 取样器(至少一个) — 断言(至少一个) — 监听器(至少一个)
2.2.1 测试计划配置:
用户定义的变量:在测试计划上可以添加用户定义的变量,相当于是全局变量。一般添加一些系统常用的配置。如果测试过程中想切换环境,切换配置,一般不建议在测试计划上添加变量,因为不方便启用和禁用,一般是直接添加用户自定义变量组件。
独立运行每个线程组:用于控制测试计划中的多个线程组的执行顺序。不勾选时,默认各线程组并行、随机执行,执行过程线程的执行顺序是不可预料的。如果勾选了独立运行每个线程组,可以保证线程组1执行完毕,才会执行线程组2,即顺序执行各线程组。
添加目录或jar包到classpath:
添加文件或jar包,此功能最常用于调用外部jar包。当脚本需要调用外部的java文件或jar包时,可以把jar包路径添加到这里,然后在beanshell中直接import进来,并调用jar包中的方法。
2.2.2 场景配置(线程组配置)
区域一: 取样器失败后策略
当某个线程中的某个请求失败
继续:线程继续执行本次循环中的剩余请求
启动下一循环:线程舍去本次循环中的剩余请求,开启下一次循环
停止线程:线程舍去本次循环中的剩余请求,不再执行下一次循环
停止测试:通知所有线程停止,正在执行任务的,执行完本次循环
立即停止测试:通知所有线程立即停止,终止所有进行中或未执行的循环。
区域二: 线程属性
线程数:如何计算线程数。参考之前的内容
Ramp-up:达到指定线程需要的时间。例如线程数为100,时间设定为10s,那么就是10s加载100个线程,每秒启动的线程数=100/10=10;
注意:
1.如果不是永久循环,线程完成循环任务后就会关闭
2.如果 ramp-up 时间内,所有线程不能启动运行完的话,时间则会顺延下去
循环次数:每个线程执行任务的循环次数
same user on each iteration:
【选中】每次循环用第一次的cookie,不再更新;可以理解为每次循环都是同一个用户。
【不选中】每次循环都是用新的cookie值;可以理解为每次循环都是不同的用户。
同时,在cookie管理器、缓存管理器、授权管理器 的配置选项中,也都增加了一个 ‘Use Thread Group configuration to control clearing’的复选配置项
持续时间(秒):脚本启动后执行的时间,如果不填线程组将不被执行,如果执行需要的时间>持续时间,执行时间覆盖执行需要的时间。
启动延迟(秒):测试计划延迟多久执行。例如16:00启动执行,延迟时间120s,脚本会在16:02执行。界面左上会显示延迟时间。
注意:调度器时间和循环次数不能同时存在!
场景配置练习:
策略一:
Ramp-up:1s 循环次数:1 线程数:100
真实场景:100人同时1秒内请求一个业务。TPS=100?
策略二:
Ramp-up:10s 循环次数:1 线程数:100
真实场景:100准备,每1秒上10个人请求一个业务。请求结束后立即断开。TPS=10?
策略三:
Ramp-up:1s 循环次数:10 线程数:100
真实场景: 1秒内100个人同时上线。每人请求一个业务10次,任务完成后立即断开。TPS=?
策略四:使用吞吐量定时器将100个线程产生的TPS维持在100,持续5分钟
Ramp-up:1s 循环次数:永远 线程数:100
吞吐量定时器:目标每分钟业务数6000
策略五:
Ramp-up:0,循环次数:永远,线程数:100,调度器:300s
真实场景: 100人准备,同时上场,无限次数执行请求,tps如何计算?假如平均响应时间是0.2s,TPS=500,但是会波动。
策略六:
Ramp-up:0,循环次数:永远,线程数:100,调度器:300s
真实场景: 100人准备,同时上场,无限次数执行请求,tps如何计算?假如平均响应时间是0.2s,TPS=500,但是会波动。
总结:
1.循环次数和线程数一起,用来控制总得请求样本数
2.在Ramp-up时间内,可以实现TPS固定
3.如果无请求总数要求,可以不使用循环次数,此时的TPS根据响应时间变化而变化
4.第三种情况下的Ramp-up时间,通常作为梯度加压的缓冲时间,便于观察压力逐步增加过程中系统的表现。达到目标线程数后需要稳定一段时间。
5.如果需要控制TPS请使用吞吐量定时器。
练习:业务指标需求–接口平均RT = 0.2s 100tps 5分钟==300s
列举出常见的线程组配置策略。
2.2.3 基本元器件的使用
元件类型:
取样器:不与其他元件发⽣交互的作⽤的元件,
逻辑控制器:只对其⼦节点的取样器有效,
配置元件:影响其范围内的所有元件
前置处理器:在其作⽤范围内的每⼀个取样器之前执⾏
定时器:对其作⽤范围内的每⼀个取样器有效
后置处理器:在其作⽤范围内的每⼀个取样器之后执⾏
断⾔:对其作⽤范围内的每⼀个取样器执⾏后的结果执⾏校验
监听器:收集其作⽤范围内的每⼀个取样器的信息并且呈现出来
相同节点加载/执⾏顺序:
配置元件—前置处理器—定时器—取样器—后置处理器—断言—监听器
1.逻辑控制器
事务控制器
作用:将多个元件合并成一个事务。
⼀个事务在分布式处理中,可能会对应多个请求。
便于按事务来统计TPS或者RT。
便于把其他元件直接作用在事务控制器上,不用单独应用于每个元件。
Generate parent sample:选中这个选项,则在聚合报告中只显示事务控制器的时间,而不显示取样器的时间。
Include duration of timer…:选中这一项会将计时器、前置处理器、后置处理器等时间计算在内,否则只统计取样器的时间。
循环控制器
作⽤:指定其⼦节点运⾏的次数,可以使⽤具体的数值,也可以使⽤变量
如果控制器
作⽤:满⾜条件执⾏其⼦结点
应用场景:1. 当前一个请求成功后,才执行某个请求
练习:当登录成功后,才执行查询城市名称
${JMeterThread.last_sample_ok}
演示说明:选项Evaluate for all children
2. 当数据中存在某些特征时,才执行某个请求
练习:在外部csv文件中存储着用户信息,当用户VIP
数据为1,表示vip用户,此时才有权利查询城市名称
勾选,expression中不能直接填写条件表达式,需要借助函数将条件表达式计算为true/false,例如:直接填写 m o d e l I d = = 5 ,是不能识别的。需要借助函数助手,生成表达式 {modelId}==5,是不能识别的。需要借助函数助手,生成表达式 modelId==