服务调优经验总结
版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | https://vearne.cc
前言
萌叔工作十多年,有不少服务调优的经验,在这里整理一下思路。希望对自己和同行有所帮助。
1. 发现问题
1.1 发现问题比解决问题难度更大
找出系统瓶颈和问题难度很大,一般只要能够找出且能够稳定复现,问题都能够被解决。
1.2 压测能够帮我们发现系统瓶颈,找出问题
压测不仅可以帮助我们发现系统瓶颈,还能用于发现死锁问题
1.3 尽可能细粒度的监控指标对发现问题帮助很大
讲几个容易忽略的细节
- 使用Cache的场景,要留意Cache的命中率
- 使用Channel的细节,要监控channel的长度,注意Channel是否写满,阻塞其它协程
- 对于比较复杂的接口,如果延迟高,需要有tracing记录,关注到底是那个环节耗时过多
- 对于MQ和数据库的场景,甚至还需要监控PageCache的命中率和使用情况、磁盘IO等等
- GC 的耗时(特别是Java中Full GC)
2. 常见的思路
2.1 绝大多数服务的系统瓶颈是IO
我们接触到的绝大多数服务,都是IO型服务,影响延迟的主要因素是IO,磁盘IO、网络IO,数据库、微服务的响应延迟等等
2.2 如果CPU是瓶颈,需要有火焰图,关注是哪个环节消耗的CPU过多?每个部分占比是否合理?(注意压测)
比如是否大量的CPU时间被消耗在了锁竞争、上下文切换、垃圾回收、调度等。
- 在Golang中,由于锁中含有自旋锁,如果对锁的竞争激烈,会有大量的CPU时间被消耗在锁上。
- 在Golang中,P设置不合理也会导致大量的上下文切换
2.3 某一类型的服务,往往会有一组需要额外注意的核心指标
某些特定的服务容易受到特定因素的影响,比如
- 基于模型的分类器,压测时要特别关注它的CPU使用率是否能够跑满
见文章
AI预测模型工程化性能调优
- 数据库服务要留意磁盘IO
2.4 GC
有GC的场景,还要特别留意GC可能带来的负面影响
2.5 日志对服务性能影响不小
写文件和写控制台的性能差不多, 每秒钟差不多30w条。假定一个请求产生30条日志,也就是说即使处理这个请求没有任何逻辑,光是打日志,QPS也就差不多1w左右。(这也是很多服务压测的QPS无法超过1w的原因)。
当你不知道该怎么调优的时候,可以试试关闭所有日志看看。?
3. 常见的优化手段
3.1 串行变并发
在IO型服务非常常见
3.2 同步变异步
常见的场景是回写数据库
3.3 单条变批量
- 比如数据需要回写数据库,可以在内存中缓存一拨,批量回写数据库,可以减少网络开销,降低数据库的开销
- 另外像写日志文件,批量写可以减少系统调用,提高写入效率。
笔者之前曾做过测试,将日志从单条同步写改为异步批量写,吞吐能力提升了1倍多。
3.4 善用Cache
在多读少写的服务中,Cache对提升服务的能力,降低延迟,效果非常显著。(别忘了监控Cache)
3.5 借鉴同行的经验
毕竟同行踩过的坑,我们还是会再踩一遍的,可以多留意github中的issue记录。
4. 其它
4.1 过早优化是万恶之源
没事别瞎折腾
4.2 越接近业务侧的优化,效果越显著
4.3 该加机器加机器,人力成本也是钱
有了一把趁手的锤子,但是又具有足够自知之明,不把所有东西都当做钉子。这种能力更是难能可贵。
5. 结尾
好多东西不整理一下,自己都快忘了。希望下次再排查问题或者调优的时候,我也能从中收益。