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

Scala Gatling中从gRPC响应传值到REST API的技术咨询

问题描述

我此前常提一些偏基础的问题,这次提问前已做了深入调研,避免给您添麻烦,这对我而言是痛并快乐的过程。以下是我更新后的代码块:

val speaker = scenario("BasicSimu")
  .exec(
    fromClientSide
      .start(thePayload)
      .header(Authorization)(s"Bearer $TokenKey")
      .extract(.pk.some)(_ saveAs "theString")
      .sessionCombiner(SessionCombiner.pick("theString"))
      .endCheck(statusCode is Status.Code.OK)
  )
  .exec{
      session => 
        val responseString = session.attributes.get("theString").toString().slice(21,28)
        val newKeyVar = session.set("myKey",responseString)
      newKeyVar
  }
  .exec(
        http("Complete_Pairing") //the little body I made here
          .post(s"url")
          .header("Content-Type","application/json")
          .body(StringBody("""{
                      "pk": {"pairingKey": "#{newKeyVar}"}
                      }"""))
          .check(status.is(200))
  )
  .exec(fromClientSide.reconciliate(waitFor = StreamEnd))

我需要提取pairingKey,将其转为字符串并截取后得到了目标值,但仍有几个问题无法自行解决:

  • 我已将pairingKey(即responseString)存入会话,需要将其传入POST REST请求的请求体中,但当前代码中#{newKeyVar}无法找到该值,想了解正确的调用方式;
  • 目前想到两种获取该值的方式:直接调用会话变量或保存到CSV,请问哪种方式更高效?
  • 我需要让gRPC流保持到获取OK响应,但调用reconciliate(waitFor = NextMessage)时流直接被取消,想了解正确的实现方式;
  • 题外话,如果在您的帮助下完成该demo,能否将其推送到您的Github仓库?

问题解答

1. 会话变量调用错误修复

你把会话里的变量名搞混了:你用session.set("myKey",responseString)把值存在了myKey这个键下,但请求体里写的是#{newKeyVar}——newKeyVar只是你代码里的局部变量名,会话根本不认它,改成#{myKey}就能正常读取了。

另外,推荐用Gatling提供的安全取值方式替代session.attributes.get,避免toString()带来的额外字符问题:

.exec{ session => 
  val responseString = session("theString").as[String].slice(21,28)
  session.set("myKey", responseString)
}

2. 两种方式的效率对比

直接调用会话变量效率高得多。会话变量是Gatling运行时的内存变量,访问完全是内存级操作,没有额外开销。而保存到CSV需要磁盘IO读写,性能损耗明显,只有当你需要跨场景/实例共享数据、或者持久化数据时才用CSV。当前场景下直接用会话变量是最优选择。

3. gRPC流保持的正确实现

reconciliate(waitFor = NextMessage)的逻辑就是收到一条消息就终止流,不符合你要等到OK响应的需求。你可以这么调整:

  • 在gRPC请求阶段,通过extract和check来监听并验证是否收到OK响应,确保流在收到目标响应前保持活跃
  • 如果服务器不会主动关闭流,不要用StreamEnd,而是基于业务响应内容来触发流的终止。示例代码如下:
fromClientSide
  .start(thePayload)
  .header(Authorization)(s"Bearer $TokenKey")
  .extract(.pk.some)(_ saveAs "theString")
  .extract(.status.some)(_ is Status.Code.OK) // 校验是否收到OK状态
  .sessionCombiner(SessionCombiner.pick("theString"))
  .endCheck(statusCode is Status.Code.OK)

另外,确保reconciliate是在确认收到OK响应之后再执行,避免提前终止流。

4. Demo推送问题

只要你拥有代码的完整版权,且代码符合仓库的贡献规范,完全可以把完善后的demo推送到我的GitHub仓库。你可以先fork仓库,提交PR,我会审核合并。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 13:35:12