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

Gatling如何实现每个虚拟用户单独执行一次JWT生成及ConnectToken请求

问题根因

你当前代码的问题出在Scala对象的初始化逻辑上:GetTokenRequest是单例对象,对象内的get_token是val类型,会在对象首次加载时一次性执行完成所有逻辑,makeJwt(props)只会调用一次生成全局固定的JWT值,后续所有虚拟用户发起请求时,client_assertion参数绑定的都是这个提前生成好的固定值,自然不会每个用户单独生成。

改造方案

我们可以把固定配置提前初始化避免重复计算,再通过Gatling的会话函数实现每个用户执行时动态生成JWT:

  1. 将固定的属性配置、文件路径等内容提前初始化,不需要每个用户重复创建
  2. 新增会话处理步骤,在用户发起获取token请求前,为当前用户单独生成JWT并存入用户私有会话
  3. 调整client_assertion参数的取值逻辑,从当前用户的会话中读取独有的JWT值

改造后代码

import java.io.File
import java.util.Properties
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import config.Config._
import util._
import headers.Headers._

object GetTokenRequest extends JwtGeneratorRSA{
  // 提前初始化固定配置,避免每个用户重复创建,节省性能
  private val props = new Properties
  // 路径和固定参数只初始化一次
  private val current = new File(".").getCanonicalPath
  props.put("issuer","cfa9c8fb-8dd6-4d7c-b142-786c3d774f64");
  props.put("audience",app_url+"/connect/token");
  props.put("resource","testRes");
  props.put("consumer_org","testOrg");
  props.put("scope","openid profile helseid://scopes/identity/pid");
  props.put("token.endpoint",app_url + "/connect/token");
  props.put("keystore.file",current+"/src/test/resources/data/cfa9c8fb-8dd6-4d7c-b142-786c3d774f64.p12");
  props.put("keystore.password","AYiPf1mZYOY60XV0tCuPIFk9UaGiOg1K");
  props.put("keystore.alias","");
  props.put("keystore.alias.password","");

  // 每个用户独立执行的逻辑
  val get_token = exec(
    // 会话处理函数:每个用户执行到这一步都会单独生成JWT存入自己的会话
    session => {
      val jwt = makeJwt(props)
      // 将生成的JWT存入当前用户私有会话
      session.set("client_jwt", jwt)
    }
  ).exec(
    http("ConnectToken")
      .post(app_url + "/connect/token")
      .headers(headers_0)
      .formParam("grant_type", "${grant_type}")
      // 从当前用户会话中读取独有的JWT
      .formParam("client_assertion", "${client_jwt}")
      .formParam("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer")
      .formParam("client_id", "${client_id}")
      .formParam("scope", "${scope}")
      .check(regex("access_token\":\"(.*?)\"").saveAs("access_token"))
  )

  // 若需要打印每个用户的JWT,可调整会话函数为如下写法:
  // session => {
  //   val jwt = makeJwt(props)
  //   println(s"用户${session.userId}的JWT: $jwt")
  //   session.set("client_jwt", jwt)
  // }
}

调用方式保持原有写法即可,注意feeder的位置:

// feeder要放在exec前面,保证参数能正确读取到会话中
.feed(csv("data/TestDataTest.csv"))
.exec(GetTokenRequest.get_token)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 08:15:04