一、线上问题回顾
国庆期间某些线上业务服务不可用,通过监控可以看到有大量的流量涌入,导致部分服务不可用,从日志监控看业务上大量报错5XX。简单调用链如下:service-A不可用。
二、问题分析猜想
首先通过查看日志初步分析发现都是mysql io/timeout问题,于是猜测数据库的瓶颈问题,所以误判为数据库瓶颈问题,但是从数据库的监控来看数据库的可用性并未降低,后其他同学发现网卡的占用率很高,于是转向查看网卡的问题,然后分析接口的调用关系后经过分析发现,如图,服务A请求服务B的时候,服务B返回的数据包比较大约几十MB数据。导致服务A的带宽打满了,网卡拥塞,导致数据无法发送出去,从而导致服务A不可用。后对线上机器进行扩容后解决问题。
三、问题场景分析
根据上述的服务可以看到,此时属于典型的io密集型的场景,大量的数据没有办法把数据实时的转发出去。导致网络拥塞,从而导致服务不可用。可以有以下解决方案:
垂直扩容(纵向扩展):服务A上的机器对CPU、内存、带宽等资源,进行升级扩容,无法进行无限的扩容;
水平扩容(横向扩展):增加更多服务实例,部署在不同机器和集群上,会导致管理成本的增加。
四、系统资源维度分析
根据上面的问题场景分析看一下具体的细节,系统资源一般包含:CPU、内存、网络IO、硬盘等;并且一般的场景分为两种:IO密集型,CPU密集型。当然也存在IO&CPU密集型的场景,但是这种场景一般不会存在,暂不关心。
五、测试机配置
指标 测试机 客户机
mem 4G 24G
net_upload 5120kbps 约等于 640kb 内网带宽100Mbps
net_download 10240kbps 约等于 1280kb 内网带宽100Mbps
cpu Intel® Xeon® Gold 6148 CPU @ 2.40GHz 2核 Intel® Xeon® Gold 6148 CPU @ 2.40GHz 8核
六、场景测试
对于测试数据仅进行特征分析,不进行数据分析,即观察分析监控曲线的走势特征。
6.1、测试前cpu占用
6.2、io密集型
为了实验的数据,使用wondershaper带宽限制,下载:1024kbps = 128kb/s,上传:512kbps = 64kb/s,并使用ab命令进行并发请求测试,ab -n 5000 -c 50 http://127.0.0.1/list,响应数据为1.3MB,测试的目的:限制出口带宽,那么就会让数据堆积在网卡上,从而模拟 case的场景。
6.2.1、cpu空闲监控走势图
6.2.2、mem监控走势图
内存使用图
内存使用百分比走势图
6.2.3、net监控走势图
上行网络走势图
下行网络走势图
6.2.4、top命令监控
6.3、cpu密集型
通过在服务端做大量的计算来模拟cpu的占用率升高,来看各个维度的数据变化。
6.3.1、cpu空闲监控走势图
6.3.2、mem监控走势图
内存使用图
内存使用百分比走势图
6.3.3、net监控走势图
上行网络走势图
下行网络走势图
6.3.4、top命令监控
七、场景分析
cpu密集型:cpu的变化较高,且占用率达到了100%,网络带宽占用不大,top命令任务的堆积数有明显增高;
io密集型:可以观察到cpu相对于cpu密集型变化的较低,网络带宽变化较明显,内存占比变化明显,且cpu变化不高。
八、总结反思
通过线上问题可以看到业务上处理的不规范,导致一个接口返回了几十MB的数据,属于设计接口时考虑不充分导致。首先应该在以后的设计中考虑到接口的返回体大小设计的合理性,避免过大的数据包。其次,服务没有做熔断降级,导致服务在不可用的时候仍然接收大量的请求,导致进一步的雪崩。最后通过此次的线上问题定位告诉我们,对于线上问题应该从多个维度出发观察,可以更加精准快速的定位到线上的问题,减少业务上的损失,包含以下:cpu、内存,网络io,磁盘io,网络耗时等。
参考文档
一分钟明白IO密集型与CPU密集型的区别:https://zhuanlan.zhihu.com/p/433310450
网卡工作原理详解:https://blog.csdn.net/tao546377318/article/details/51602298
图解Linux网络包接收过程:https://zhuanlan.zhihu.com/p/256428917
Linux 网络协议栈收消息过程-Ring Buffer:https://ylgrgyq.github.io/2017/07/23/linux-receive-packet-1/