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

在上下文管理器外标记Locust请求响应状态的实现方案咨询

Locust 请求封装后手动标记请求状态的解决方案

原方案失效原因

Locust 中使用catch_response=True参数获取的响应对象,其success()/failure()方法的生效依赖于响应上下文管理器的作用域。当get_doc函数执行完毕返回后,该上下文已被销毁,后续再调用这两个方法不会触发Locust的请求统计逻辑,因此原方案无法生效。

兼容普通Requests的最优实现方案

以下方案完全满足不侵入behavior业务逻辑、支持普通Requests会话调用的约束,可根据业务复杂度选择:

方案1:手动触发统计事件(推荐,适配性更强)

通过Locust全局统计事件上报请求结果,无需依赖响应上下文,同时对普通Requests场景做空实现兼容。

代码实现

首先导入依赖:

from locust import events
from locust.clients import HttpSession
import requests

改造get_doc函数:

def get_doc(session, meth, url):
    if isinstance(session, HttpSession):
        # Locust场景下关闭自动上报,避免统计重复
        with session.request(meth, url, catch_response=True) as resp:
            doc = parse(resp.content)
            # 保存请求元数据用于手动上报
            req_meta = {
                "request_type": meth,
                "name": url,
                "response_time": resp.elapsed.total_seconds() * 1000,
                "response_length": len(resp.content)
            }
            # 挂载状态标记方法
            doc.mark_success = lambda: events.request_success.fire(**req_meta)
            doc.mark_failure = lambda exc: events.request_failure.fire(exception=exc, **req_meta)
            return doc
    else:
        # 普通Requests场景正常执行,挂载空实现兼容调用
        resp = session.request(meth, url)
        doc = parse(resp.content)
        doc.mark_success = lambda: None
        doc.mark_failure = lambda exc: None
        return doc

业务侧调用(无任何Locust专属逻辑)

def behavior1(session):
    doc = get_doc(session, "GET", url1)
    if not doc_ok(doc):
        doc.mark_failure(Exception("Document not as expected"))
    else:
        doc.mark_success()
    doc2 = get_doc(session, "GET", url2)
    # 其余业务逻辑不变

方案2:校验逻辑入参(适合校验规则固定的场景)

将业务校验函数作为可选参数传入get_doc,在响应上下文内完成状态标记,无需额外处理事件。

代码实现

def get_doc(session, meth, url, validator=None):
    if isinstance(session, HttpSession):
        with session.request(meth, url, catch_response=True) as resp:
            doc = parse(resp.content)
            if validator:
                is_valid, err_msg = validator(doc)
                resp.success() if is_valid else resp.failure(err_msg)
            return doc
    else:
        resp = session.request(meth, url)
        return parse(resp.content)

业务侧调用

def behavior1(session):
    # 仅传入业务校验规则,无Locust专属代码
    doc = get_doc(session, "GET", url1, validator=lambda doc: (doc_ok(doc), "Document not as expected"))
    doc2 = get_doc(session, "GET", url2, validator=lambda doc: (doc2_ok(doc), "Doc2 format error"))
    # 其余业务逻辑不变

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 22:15:03