如何在Locust脚本中使用多主机名(URL)实现跨API令牌调用?
Locust令牌获取与复用解决方案
针对你需要调用不同API获取令牌再调用其他接口的场景,分两种常见情况给出具体实现方案,同时分析events机制可能踩的坑:
一、每个用户专属令牌(最常用场景)
如果每个虚拟用户需要独立获取令牌(比如不同账号登录),直接在User类的on_start方法中处理即可,这比events机制更直观,不容易出错:
from locust import HttpUser, task class AuthenticatedUser(HttpUser): def on_start(self): # 调用登录/令牌接口,替换成你的实际API和参数 login_response = self.client.post( "/api/auth/get-token", json={"username": self.username, "password": self.password} ) # 解析令牌,根据实际返回结构调整 self.token = login_response.json().get("access_token") # 全局设置headers,后续所有请求自动携带令牌 self.client.headers.update({"Authorization": f"Bearer {self.token}"}) # 可以在类里定义用户凭证,或者从外部加载 username = "test_user" password = "test_pass" @task(3) def access_protected_resource1(self): # 直接调用受保护接口,无需重复设置令牌 self.client.get("/api/protected/data1") @task(1) def access_protected_resource2(self): self.client.post("/api/protected/data2", json={"key": "value"})
为什么不用events? 因为events是全局事件,spawn_user事件虽然能触发用户创建时的逻辑,但on_start是Locust官方推荐的用户初始化钩子,专门用来处理每个用户的前置操作,代码更简洁易维护。
二、全局共享令牌(所有用户共用)
如果所有虚拟用户可以复用同一个令牌(比如客户端凭证模式获取的令牌),可以用events.test_start在测试启动前获取一次,然后所有用户共用:
from locust import HttpUser, task, events import requests # 全局变量存储令牌 global_token = None @events.test_start.add_listener def fetch_global_token(environment, **kwargs): global global_token # 调用全局令牌接口,替换成你的实际地址和参数 token_response = requests.post( "https://your-api-domain.com/api/auth/global-token", json={"client_id": "your_client_id", "client_secret": "your_secret"} ) global_token = token_response.json().get("access_token") class SharedTokenUser(HttpUser): def on_start(self): # 给当前用户的请求客户端设置全局令牌 self.client.headers.update({"Authorization": f"Bearer {global_token}"}) @task def access_shared_resource(self): self.client.get("/api/shared/resource")
注意: 如果令牌有过期时间,需要额外处理刷新逻辑,比如在test_start里启动定时任务刷新全局令牌,或者在任务里判断令牌是否过期再刷新。
三、你用events没得到预期结果的常见原因
- 事件选择错误:如果想给每个用户单独获取令牌,却用了
test_start(全局只执行一次),导致所有用户用同一个令牌,或者令牌没正确传递到用户实例。 - 令牌存储位置错误:在事件回调里把令牌存在局部变量里,没有传递到用户的
client或实例属性中,导致任务里无法访问。 - 异步/同步问题:如果用了异步Locust,events回调的异步逻辑没处理好,导致令牌还没获取到用户就开始执行任务。
内容的提问来源于stack exchange,提问作者lordgubbi
相关产品推荐
相关产品推荐

