You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gatling中gRPC请求失败时如何强制虚拟用户退出场景?

问题

我配置了如下的双向流(bidiStream):

.exec(
    bidiStream_conf
      .start("#{payload}")
      .header(metadataObject.Authorization)(s"Bearer ${Key}")
      .extract(_.pk.some)(_ saveAs "var")
      .sessionCombiner(SessionCombiner.pick("var"))
      .endCheck(statusCode is Status.Code.OK)
  )
.exitHereIfFailed
.exec(REST_req)
.exec(bidiStream_conf.complete)
.exec(bidiStream_conf.reconciliate(waitFor = NextMessage))

我希望当流失败时强制虚拟用户(V.User)退出,因此传入了无效密钥,运行后得到如下日志:

gRPC stream completion:
status=
PERMISSION_DENIED, description: code = E3014, message = Token is invalid!
trailers=
content-type: application/grpc
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
15:45:32.700 [DEBUG] c.g.p.g.g.s.BidiStreamCall - Client issued message but stream bidiStream_conf already completed

================================================================================
2023-11-30 15:45:34                                           5s elapsed
---- Requests ------------------------------------------------------------------
> Global                                                   (OK=2      KO=1     )
> bidiStream_Req                                           (OK=0      KO=1     )
> REST_Req                                                 (OK=1      KO=0     )
---- Errors --------------------------------------------------------------------
> grpcStatusCode.find.is(OK), but actually found PERMISSION_DENI      1 (100.0%)
ED

可见后续REST API仍被执行,我认为使用exitHereIfFailed的方式有误,请问如何正确操作才能强制虚拟用户完全停止整个场景?

解决方案

问题的核心是gRPC双向流的失败为异步触发,exitHereIfFailed仅同步判断当前步骤状态,无法捕获后续流回调中出现的错误,导致后续REST请求仍会执行。以下是几种可行的解决方式:

  • 同步等待流完成
    在双向流配置中添加.await,确保虚拟用户等待流完成后再执行后续步骤,让流的失败状态同步到当前步骤,此时exitHereIfFailed即可生效:

    .exec(
        bidiStream_conf
          .start("#{payload}")
          .header(metadataObject.Authorization)(s"Bearer ${Key}")
          .extract(_.pk.some)(_ saveAs "var")
          .sessionCombiner(SessionCombiner.pick("var"))
          .endCheck(statusCode is Status.Code.OK)
          .await // 等待流完成,同步错误状态到当前步骤
      )
    .exitHereIfFailed
    .exec(REST_req)
    .exec(bidiStream_conf.complete)
    .exec(bidiStream_conf.reconciliate(waitFor = NextMessage))
    
  • 异步错误触发立即终止
    如果不需要等待流完成,希望流一失败就立刻终止虚拟用户,可在流的onFailure回调中直接调用exitNow:

    .exec(
        bidiStream_conf
          .start("#{payload}")
          .header(metadataObject.Authorization)(s"Bearer ${Key}")
          .extract(_.pk.some)(_ saveAs "var")
          .sessionCombiner(SessionCombiner.pick("var"))
          .endCheck(statusCode is Status.Code.OK)
          .onFailure { session =>
            session.markAsFailed("gRPC流权限验证失败")
            exitNow // 立即终止虚拟用户,不再执行后续操作
          }
      )
    .exec(REST_req)
    .exec(bidiStream_conf.complete)
    .exec(bidiStream_conf.reconciliate(waitFor = NextMessage))
    
  • 仅在流成功时执行后续操作
    使用doIfSucceeded包裹所有后续操作,确保只有当双向流成功时才执行REST请求等步骤:

    .exec(
        bidiStream_conf
          .start("#{payload}")
          .header(metadataObject.Authorization)(s"Bearer ${Key}")
          .extract(_.pk.some)(_ saveAs "var")
          .sessionCombiner(SessionCombiner.pick("var"))
          .endCheck(statusCode is Status.Code.OK)
      )
    .doIfSucceeded {
      _.exec(REST_req)
        .exec(bidiStream_conf.complete)
        .exec(bidiStream_conf.reconciliate(waitFor = NextMessage))
    }
    

以上三种方式都能确保当gRPC双向流因无效密钥失败时,虚拟用户会停止执行后续操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 06:08:20