概要
本文是根据自己压测的经历总结出来的小本本,遇到压测的时候提前看一眼,能节省自己的时间,少熬夜,有说的不对地方,欢迎大家评论留言。
压测原则
我觉得性能优化是个持续的过程,所以我们得有原则的去执行,有4个原则
- 压测期间,除非bug,否则尽可能不改或者最小范围的改动代码
- 以各种监控为主、服务日志为辅定位和优化性能问题
- 在可容忍的区间内优化性能,尽量避免扩大工作面
- 大版本变更的压测,最好是结对压测,处理复杂问题能高效
粗俗一点讲:尽量不改代码、优化有度、找一只合适的小黄鸭
压测常见问题
压测可能会遇到这些方面的问题:缓存、数据库、同步处理逻辑、程序内部问题、下游依赖的性能问题
缓存
使用复杂度高的命令:
使用O(n)或者更高复杂度的命令,但是未严格控制n
设计的缓存数据不合理:
key拆分过细,导致一次请求多次IO,随着业务复杂,单次业务处理的时间复杂度越来越高
key不拆分形成大key,单次响应体积过大,影响性能
redis连接配置不合理:
不合理的空闲检测时间,没有针对业务高峰期预热线程或者连接,导致建连接会阻塞住业务逻辑
数据库
索引问题
缺少或者设置错误索引,导致一次查询太多数据,甚至慢sql
数据缓存问题
没有恰当的采用缓存,导致sql次数太多
同步处理逻辑
过多同步逻辑:
同步业务中处理了过多时效性不高的逻辑
异步逻辑访问db不加控制:
一个业务逻辑可能会发出多个消息异步入库,一旦遇到请求尖刺,异步入db的请求放大比非常明显扫描二维码关注公众号,回复: 13166220 查看本文章
程序内部问题
业务代码问题
比如业务代码中申请了大对象,或者是在循环中处理业务逻辑,导致gc出现卡顿
rpc依赖产生的性能问题
错误处理不合理
调用下游业务的超时不合理,过长或者过短
调用下游的重试次数也不合理,过多或者过少
常见应对措施
我们对症下药,逐个来说
缓存问题解决
减少缓存IO
小key整合,大key拆分,控制缓存IO的放大比和单次请求的响应体积
及时盯着redis的slowlog,尝试优化占比最大或者耗时最长的几个命令
热点的数据随机打散存储, 降低单台缓存服务器的IO
使用本地缓存优化热点数据
将数据分片存储,减少本地缓存的存储空间
写热点数据时使用多备份,减少集群请求不均的情况
保存数据时,存上100份,请求时随机读数据,让请求分散到多个redis-server上
同步处理优化
找出可以异步的逻辑,转入消息队列
消费消息写db时,增加db限流保护
程序内部问题
手动预热线程池和资源连接
如果有尖刺场景,提前预热的资源池线程
检视代码,减少大对象的逻辑
比如使用stream替换for,减少暂存结果的中间变量,避免一种大对象的case
rpc重试和异步重试
做好本地重试
对于下游依赖的性能问题,需要协调下游做针对性优化,没得说
处理好错误响应
设置降级响应,减少系统性能问题导致的影响面
控制rpc放大比
监控服务间rpc的次数,及时对同一个rpc的多次调用,及时将rpc的结果缓存到堆栈上,或者将多次调用合并为同一个