昨天有个朋友问题对mina是否有什么优化的资料,他这边一个系统压到500并发就上不去了,开始在看中国好声音,也没多想,直接说我这边没有。后来中间休息的时候,发现回答的有点问题,心里觉得其实应该告诉他压测的tips,找到瓶颈才能知道问题所在,昨晚初略的说了一下,今天把以前的一些经历回忆一下,贴出来,多少对一些新人有帮助。
这里主要还是说一下经验,具体的工具不太多的说了,以前写的一些blog多少有提到。首先判断压测需要开始查问题的情况是加并发用户,TPS不增长了,甚至开始下跌了,RT不动了,甚至开始上涨了。(这两者有时候是有关联变化的,有时候是没有关联的变化的)
然后开始分析问题,第一件要做的事情:判断自己用的压测方式和工具(lr,ab,自己写的多线程客户端)是否正确,有好几次都是找了一圈发现测试端出现了问题(这是很悲催的),这类问题如何定位?找恒定基准(空挂web容器,mock对象固化RT)。
第二件事情,用操作系统的资源监测命令(linux 命令翻出来看看),cpu利用率,load,memory使用情况(cache,swap,应用占用),上下文切换情况,io wait,网络数据量,数据包丢包情况,文件句柄配置等等。根据这些指标判断,在用户并发增加的时候,哪些指标变化的厉害,甚至已经明显成为瓶颈。如果你是java应用,那么多看看jvm的gc,线程dump出来看看是否有大量lock,或者有单线程吃掉固定的cpu等等。
第三件事情,开始定位到底什么引起了这些基础资源成为瓶颈。首先先要排除依赖系统的问题,所谓依赖系统,比如web容器,集中式缓存,db等等,这些系统通常你没有办法debug,最重要的是去看看他们的log,对于warning,error特别注意,例如nginx对于数据包上下行会有配置,到一定大小就开始借助磁盘来缓解内存压力,不留意压力就上不去了,同时io也会很多。接着开始拆解你应用的各个模块,mock的方法来保证无消耗接口依赖,这样再反复测试定位问题。大志定位到某一个模块有影响的时候,一定要注意,这只是嫌疑犯,如果你写过有指针的语言你就会理解,往往问题发生在非爆发点。同时要提醒一点的是,很多时候当你真实的判断出一个瓶颈点的时候,优化了它,也许性能更低,为啥,例如A和B两个模块,A是瓶颈tps为30,B的tps是35, 此时你把A优化到了tps为50,但是对于B来说压力明显就增大了,此时B可能由于资源压力tps开始下降(就是前面提到的并发用户上升除了保持平线,还可能下降)。
可能说到这里很多人觉得这都是常识,也没啥实质内容,其实首先就是找问题,然后就是用你语言熟悉度和业务设计来破隙问题。最后说最常用的几个所谓的优化万精油:
1.减少关键业务路径的RT总和。很多时候纠结与所谓的代码级别省,不如业务直接优化一点来的天崩地裂。(基础系统除外)
2.瓶颈资源,例如第二步说的所有指标资源和依赖系统的资源(例如web容器的线程数等)等。对瓶颈资源做两种处理:a.高效使用。(例如db的批量处理,缓存的批量获取,磁盘的批量刷出)b.少用。对数据一致性要求不高的情况下可以做一些本地缓存等等。c.快速释放。写过事件驱动代码的同学应该深有体会,将业务处理切割细化以后,原本hold的资源也会被碎片化的使用。(其实我们学习计算机cpu演进的时候就能看到这通俗的道理),快速释放意味着同样资源可以服务更多请求者。d.交换资源。磁盘换内存,多核cpu处理能力换存储。有兴趣可以看看TOP已经用了两年多的流式计算框架里面的设计细节。
3.换依赖,包括web容器,集中式缓存,磁盘等等,换他们并不一定是他们不好,而是也许数据结构不支持导致需要多次操作(集中式缓存),多系统间有更好的私有交互协议(反向代理和web容器之间),本身被革命了(固态硬盘)。
先写到这里,多少应该有点帮助,或者你遇到类似问题会有点共鸣,如果你是做业务系统,那么这个万精油的顺序就是你最好的改进顺序。
还是那句话,优化这东西就四步:1.找。2.定位。3.分析。4.迭代平衡瓶颈。