如何做压力测试?Locust模拟百人同时翻译
🌐 AI 智能中英翻译服务 (WebUI + API)
📖 项目简介
本镜像基于 ModelScope 的CSANMT (神经网络翻译)模型构建,提供高质量的中文到英文翻译服务。相比传统机器翻译,CSANMT 模型生成的译文更加流畅、自然,符合英语表达习惯。系统已集成Flask Web 服务,支持直观的双栏式对照界面,并修复了结果解析兼容性问题,确保输出稳定可靠。
💡 核心亮点: -高精度翻译:基于达摩院 CSANMT 架构,专注于中英翻译任务,准确率高。 -极速响应:针对 CPU 环境深度优化,模型轻量,翻译速度快。 -环境稳定:锁定 Transformers 4.35.2 与 Numpy 1.23.5 黄金版本组合,杜绝依赖冲突。 -智能解析:内置增强版结果提取器,自动适配不同格式的模型输出。
该服务不仅适用于个人用户通过 WebUI 进行交互式翻译,也开放了标准 RESTful API 接口,便于集成至第三方系统或自动化流程中。在实际部署前,一个关键问题是:当大量用户并发请求时,系统能否保持稳定响应?
本文将使用Locust—— 一款开源的分布式负载测试工具,模拟100 名用户同时发起翻译请求,全面评估该翻译服务的性能表现,并给出可落地的压力测试实践方案。
🧪 压力测试目标与场景设计
明确测试目标
本次压力测试的核心目标是: - 验证系统在高并发下的稳定性- 测量平均响应时间(RT) - 发现潜在瓶颈(如 CPU 占用过高、内存泄漏、接口超时等) - 判断当前架构是否满足生产级部署要求
设计真实业务场景
我们模拟如下典型用户行为: 1. 用户向/translate接口发送 POST 请求 2. 请求体包含一段中文文本(如“今天天气很好”) 3. 服务返回对应的英文翻译结果(如 "The weather is nice today.")
我们将使用 Locust 编写用户行为脚本,设置100 个并发用户,每秒增加 2 个新用户(hatch rate),持续运行 5 分钟以上,观察系统指标变化。
🛠️ Locust 环境准备与安装
安装 Locust
确保本地或测试服务器已安装 Python 3.8+,执行以下命令:
pip install locust建议在虚拟环境中操作以避免依赖冲突:
python -m venv locust-env source locust-env/bin/activate # Linux/Mac # 或 locust-env\Scripts\activate # Windows pip install locust验证安装
运行以下命令检查版本:
locust --version输出类似locust 2.27.0表示安装成功。
🧩 编写 Locust 测试脚本
创建locustfile.py
在项目根目录创建locustfile.py,内容如下:
from locust import HttpUser, task, between import json import random # 可选的中文句子池,用于多样化请求数据 SENTENCES = [ "今天天气很好。", "人工智能正在改变世界。", "这个翻译模型非常准确。", "欢迎使用我们的在线翻译服务。", "深度学习技术越来越成熟。", "请帮我把这句话翻译成英文。", "这是一个高性能的CPU推理方案。", "模型已经完成加载并准备就绪。" ] class TranslationUser(HttpUser): # 用户思考时间:每两个任务之间等待 1~3 秒 wait_time = between(1, 3) @task def translate(self): # 随机选择一句中文进行翻译 text = random.choice(SENTENCES) # 构造请求数据 payload = { "text": text } headers = {'Content-Type': 'application/json'} # 发起 POST 请求到翻译接口 with self.client.post("/translate", data=json.dumps(payload), headers=headers, catch_response=True) as response: if response.status_code == 200: try: result = response.json() if "translation" not in result: response.failure("Missing 'translation' field in response") except Exception as e: response.failure(f"Invalid JSON: {e}") else: response.failure(f"Got status code {response.status_code}")脚本说明
| 组件 | 功能 | |------|------| |HttpUser| 表示每个模拟用户都是 HTTP 客户端 | |@task| 标记要执行的任务方法 | |between(1,3)| 模拟用户操作间隔,更贴近真实行为 | |random.choice(SENTENCES)| 避免完全重复请求,提升测试真实性 | |catch_response=True| 允许手动控制成功/失败判定 | | JSON 校验逻辑 | 确保返回结果结构正确 |
▶️ 启动 Locust 压力测试
启动 Flask 服务
确保你的 AI 翻译服务已在后台运行:
python app.py # 或根据实际启动方式执行假设服务监听在http://localhost:5000
启动 Locust Web UI
在另一终端运行:
locust -f locustfile.py --host http://localhost:5000打开浏览器访问http://localhost:8089,进入 Locust 控制台。
配置用户参数
- Number of users to simulate:
100 - Spawn rate (users spawned per second):
2 - Host (optional):
http://localhost:5000
点击 “Start swarming” 开始压测。
📊 实时监控与数据分析
关键指标解读
Locust 提供以下核心指标:
| 指标 | 含义 | 健康阈值建议 | |------|------|-------------| |Requests/s| 每秒请求数(吞吐量) | 越高越好 | |Median Response Time| 中位响应时间 | < 1s 为佳 | |90% / 95% Percentile| 大部分请求延迟上限 | < 2s | |Failures| 失败率 | 应接近 0% | |RPS (per second)| 实时请求速率曲线 | 观察波动情况 |
示例输出(节选)
Type Name # reqs # fails Avg Min Max Median (ms) --------|----------------------|---------|-----------|--------|--------|-------|-------- POST /translate 4860 0(0.00%) 867 312 2105 820 --------|----------------------|---------|-----------|--------|--------|-------|-------- Aggregated 4860 0(0.00%) 867 312 2105 820说明: - 总共发送了 4860 个请求 -无失败请求- 平均响应时间为867ms- 最大延迟为 2.1s,出现在系统负载高峰时段
🔍 性能瓶颈分析与优化建议
监控系统资源
使用top或htop查看后端服务资源占用:
htop重点关注: -CPU 使用率:是否长期 >90% -内存使用:是否有持续增长趋势 -Python 进程数量:单进程可能成为瓶颈
发现问题
测试过程中发现: - 单个 Flask 进程 CPU 利用率达 95%+ - 当并发超过 80 用户时,响应时间明显上升 - 内存稳定,无泄漏迹象
✅ 优化建议
1. 使用 Gunicorn + 多工作进程
替换默认 Flask 开发服务器,提升并发处理能力:
pip install gunicorn gunicorn -w 4 -b 0.0.0.0:5000 app:app
-w 4表示启动 4 个工作进程,充分利用多核 CPU
2. 添加缓存机制(Redis / Memory Cache)
对高频短句做缓存,减少重复推理开销:
from functools import lru_cache @lru_cache(maxsize=1000) def cached_translate(text): return model.translate(text)3. 启用异步预热与批处理(进阶)
若支持批量输入,可合并多个请求为 batch,提高 GPU/CPU 利用率。
4. 设置超时与限流
防止恶意刷量导致服务崩溃:
from flask_limiter import Limiter limiter = Limiter(app, key_func=get_remote_address) app.route('/translate', methods=['POST']) @limiter.limit("30 per minute") def translate(): ...🔄 自动化测试脚本(非 Web 模式)
对于 CI/CD 场景,可直接运行命令行模式:
locust -f locustfile.py \ --headless \ --users 100 \ --spawn-rate 2 \ --run-time 5m \ --stop-timeout 10 \ --host http://localhost:5000参数说明: ---headless:无界面模式 ---run-time 5m:运行 5 分钟后自动停止 ---stop-timeout:优雅关闭等待时间
可在 Jenkins/GitLab CI 中集成此命令,实现每日性能回归测试。
📈 压测结果总结与决策参考
| 项目 | 当前表现 | 是否达标 | 建议 | |------|----------|----------|------| | 并发支持 | 支持 80~100 用户 | ⚠️ 边缘稳定 | 建议启用 Gunicorn | | 平均响应时间 | 867ms | ✅ 可接受 | 可进一步优化至 500ms 内 | | 错误率 | 0% | ✅ 优秀 | 保持监控 | | 资源消耗 | CPU 高负载 | ❌ 存在风险 | 优化模型或扩容 |
📌 结论:当前系统在轻度并发下表现良好,但面对百人级并发时存在性能瓶颈。推荐上线前采用 Gunicorn 多进程部署,并加入请求限流机制,以保障服务稳定性。
🎯 最佳实践总结
- 测试即代码:将
locustfile.py纳入版本管理,与业务代码同步迭代 - 贴近真实场景:使用多样化的输入数据,避免单一请求造成偏差
- 分阶段加压:从 10 用户逐步增至 100,观察拐点
- 结合系统监控:配合
prometheus + grafana实现全链路可观测性 - 定期回归测试:每次模型更新或代码变更后重新压测
🚀 下一步建议
- 将 Locust 测试容器化,与 Docker Compose 一起编排测试环境
- 集成 Prometheus Exporter,采集更多内部指标(如模型推理耗时)
- 尝试分布式压测:使用多台机器协同发起请求,突破单机限制
- 对比不同模型版本的性能差异(如 Tiny vs Base 版本)
📚 参考资料
- Locust 官方文档
- Gunicorn 部署指南
- ModelScope CSANMT 模型页
- Flask-Limiter 限流插件
🎯 温馨提示:性能测试不是一次性的任务,而应作为 DevOps 流程中的常态化环节。只有持续关注系统表现,才能打造真正可靠的 AI 服务。