Locust模拟真实用户并发及优化建议
第一部分为什么要压测因为生产环境不会跟你商量你可以把API想象成一家餐厅的后厨。本地跑通就像你一个人在后厨炒菜流水线得很顺。但突然来了一百个客人同时点餐后厨就乱套了——锅不够、灶不够、配菜来不及切。压测就是在开业前先请一群朋友来“假装点餐”看看后厨到底能扛多少桌瓶颈在灶台CPU还是配菜师傅数据库连接。我之前有个项目上线前自我感觉良好结果活动当天用户量稍微上来点接口响应时间直接从50ms飙升到5秒。为啥因为用了默认的uvicorn单进程只能跑满一个CPU核心而数据库连接池又没限制每个请求都新建连接数据库直接拒绝服务。 要是早做压测这些坑都能提前发现。 第二部分压测工具大乱斗我为什么偏爱这一款工欲善其事必先利其器。市面上压测工具一堆我用下来感受是这样的⚡ab(Apache Bench)老牌工具一条命令就能用。但缺点很明显——不支持HTTP Keep-Alive测不出真实复用连接的情况而且对异步框架支持不友好容易低估性能。⚡wrk性能强悍支持Lua脚本定制。但你要会写Lua对纯Python开发者来说有点门槛。⚡Locust我的最爱❤️ 纯Python写压测脚本可以模拟用户各种行为自带Web UI看实时图表还能分布式施压。最关键的是作为Python程序员改脚本就跟改业务代码一样顺手。今天咱们就用Locust做演示因为它能最贴近地模拟真实用户并发——比如有的用户登录有的浏览商品有的下单每个操作之间还有等待时间。 第三部分手把手实战——压测一个FastAPI接口 1. 先写个简单的FastAPI应用假设我们有一个返回商品信息的接口里面会查询数据库这里用sleep模拟IO。# main.py from fastapi import FastAPI import asyncio app FastAPI() app.get(/products/{product_id}) async def get_product(product_id: int): # 模拟数据库查询耗时 await asyncio.sleep(0.1) # 假设查询需要100ms return {product_id: product_id, name: 程序员防脱发洗发水}⚠️ 警告千万别用time.sleep()会阻塞整个事件循环必须用await asyncio.sleep()或调用异步库。 2. 编写Locust压测脚本安装locustpip install locust。新建locustfile.py# locustfile.py from locust import HttpUser, task, between class ProductUser(HttpUser): wait_time between(1, 3) # 用户模拟等待1~3秒再发请求 task def view_product(self): # 随机访问商品1~100 product_id random.randint(1, 100) self.client.get(f/products/{product_id}) # 可以加更多task模拟不同行为比如登录、下单等 3. 开始压测启动FastAPI应用uvicorn main:app --host 0.0.0.0 --port 8000注意这是单进程仅用于初步测试。另起终端运行Locustlocust -f locustfile.py --hosthttp://localhost:8000。打开浏览器访问http://localhost:8089设置总用户数1000每秒启动10个点击开始。你会看到漂亮的实时图表RPS每秒请求数、响应时间、失败率。我第一次压这个接口单进程下RPS大概在900左右平均响应时间1.2秒CPU直接飙到100%。瓶颈出来了——单核CPU是短板。 第四部分优化“三板斧”让并发飞起来发现问题就好办了。针对FastAPI项目我总结了三步最有效的优化动作第一板斧多进程 GunicornUvicorn单进程只能吃满一个核。用Gunicorn启动多个Uvicorn worker就能利用多核CPU。命令示例gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app --bind 0.0.0.0:8000-w 4表示启动4个worker进程一般设置为CPU核心数×21。再压测RPS直接涨到3000响应时间降到400ms。第二板斧数据库连接池之前我偷懒每次请求都新建数据库连接导致数据库连接数爆满。改用连接池比如databases库或SQLAlchemy的池限制最大连接数并复用连接。配置示例from databases import Database database Database(postgresql://user:passlocalhost/db, min_size5, max_size20)第三板斧缓存热点数据如果接口查的是频繁访问的商品信息加一层Redis缓存QPS能再翻倍。别忘了设置合理的过期时间。优化后再压测同样1000用户RPS可以稳定在5000以上平均响应时间200ms以内。 第五部分那些年我踩过的坑你一定要避开坑1在生产环境直接压测—— 有一次我图省事对线上服务小流量压测结果把数据库打挂了。一定在预发布环境或单独压测环境搞坑2忘了调整系统文件句柄数—— Linux默认打开文件数1024高并发下很快会达到上限导致socket创建失败。记得修改/etc/security/limits.conf。坑3压测客户端自身成为瓶颈—— 单机压测时如果客户端机器性能不够可能客户端先挂了。可以用Locust的分布式模式多台机器一起压。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2482733.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!