You need to enable JavaScript to run this app. Gatling场景与链路开发中def与val的使用时机最佳实践咨询
优惠活动
大模型
产品
解决方案
定价
更多

Gatling场景与链路开发中def与val的使用时机最佳实践咨询

Gatling场景与链路开发中val/def的使用最佳实践

概念对齐(面向Java开发背景)

先建立和Java语义一致的认知,避免Scala语法带来的认知偏差:

  • val是类加载阶段完成一次性初始化的不可变常量,全程内存中只存在一个实例,等价于Java中类加载时就赋值的static final常量。
  • def是每次被调用时才会执行函数体、生成全新对象的方法,每次调用都会产生独立的实例,等价于Java中每次调用都会new新对象的普通实例方法。

Gatling的DSL组件(ChainBuilder、ScenarioBuilder、HTTP请求构造器等)本身是不可变的,不存在共享状态污染问题,但两者的实例化时机差异,会直接影响运行时灵活性、内存开销和最终执行行为。

分场景适配规则

  • 结构固定、无动态依赖的链路,优先用val
    这类组件本身逻辑不变,不需要在运行时动态拼接内容,用val可以避免重复实例化的内存开销。
    参考现有代码中的定义,这类写法完全符合val的适用场景:

    val loginFlowWithExit = exec(loginFlow).exitHereIfFailed
    val teacherBranching = group("teacherBranching") {
      exec(loginFlow)
        .exec(session => sessionSetSessionVariable(session))
        .exec(execFlaggedScenario(teacherDashboard))
        .exec(logout())
    }
    

    另外顶层Scenario定义(比如代码中的rootTeacherScenario)因为只需要在Simulation启动时注册一次,必须用val声明——如果写成def,Simulation初始化时会因为反复调用生成重复的场景定义,导致框架加载异常。

  • 依赖外部配置、需要动态拼接逻辑的链路,必须用def
    针对提到的randomSwitch这类分支结构是否适合放在def里的问题:完全适合,甚至多数场景下必须用def。
    核心原因是分支链路通常需要根据业务需求调整权重、替换挂载的子流程,用def声明时可以把可变的配置、子流程作为方法参数传入,每次调用时动态生成匹配当前需求的分支链路,不会因为val的单次初始化特性导致配置变更不生效。
    比如现有代码中的teacherViewResources,如果后续需要给不同角色配置不同的分支占比、替换分支内的子流程,用def的扩展性会远好于val:

    // 适合用def的分支结构:可灵活调整子链路、分支权重
    private def teacherViewResources(
      launchChain: ChainBuilder, 
      assignChain: ChainBuilder, 
      weightConfig: Map[String, Double]
    ): ChainBuilder =
      exec(viewResourcesFlow)
        .randomSwitch(
          weightConfig("launch") -> pause(1,2).exec(launchChain),
          weightConfig("assign") -> pause(1,2).exec(assignChain),
          weightConfig("next") -> pause(1,2).exec(teacherResourcesNext)
        )
    

    当然,如果你的randomSwitch分支权重、挂载的子流程永远固定,没有调整需求,写成val也不会有功能问题,只是会损失灵活调整的扩展性。

常见避坑点

  • 不要把依赖Session动态取值的链路硬写成val:如果链路里需要从Session读取变量拼接请求路径、请求头,用def才能保证每个虚拟用户走到该节点时,都能读取到自己Session里的最新值,不会因为类加载时的单次初始化,把请求参数写死成第一个初始化实例的内容。
  • 不要把所有链路都写成def:比如顶层场景、无动态逻辑的公共子链路,如果每次调用都重新生成DSL对象,会在Simulation启动阶段产生大量重复实例,拖慢框架加载速度。
  • 现有代码中的teacherLaunchResource这类无参数、逻辑固定的单步链路,完全可以从def改成val,减少不必要的对象生成和方法调用开销。

内容的提问来源于stack exchange,提问作者Francislainy Campos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.25 17:45:01