27丨案例:带宽消耗以及Swap(上)

今天我们来看一个真实的案例。事情是这样的,之前有人在微信上问我一个问题,这个问题的现象很典型:典型的TPS上不去,响应时间增加,资源用不上。

大概的情况是这样的:有两台4C8G的服务器,一台服务器上有2个Tomcat,一台服务器上是DB。压测的混合场景有4个功能模块,其中3个访问一个Tomcat,另外一个访问一个Tomcat。

Tomcat的监控页面如下:

应用服务器系统资源监控页面如下:

数据库服务器系统资源监控如下:

JMeter结果如下:

综上现象就是,单业务场景执行起来并不慢,但是一混合起来就很慢,应用服务器和数据库服务器的系统资源使用率并不高。请问慢在哪?

这是非常典型的询问性能问题的方式,虽然多给了系统资源信息,但是这些信息也不足以说明瓶颈在哪。

为什么呢?在现在多如牛毛的监控工具中,除非我们在系统中提前做好分析算法或警告,否则不会有监控工具主动告诉你, 监控出的某个数据有问题,而这个只能靠做性能分析的人来判断。

我在很多场合听一些“专家”说:性能分析判断要遵守木桶原理。但是在做具体技术分析的时候,又不给人说明白木桶的短板在哪里。这就好像,一个赛车手说要是有一个各方面都好的车,我肯定能得第一名,但是,我没有车。

话说出来轻而易举,但是请问木桶的短板怎么判断呢?因为CPU高,所以CPU就是短板吗?所以就要加CPU吗?这肯定是不对的。

因为这个例子并不大,所以可以细细地写下去。今天文章的目的就是要告诉你,性能问题分析到底应该是个什么分析思路。

分析的第一阶段

画架构图

做性能测试时,我们需要先画一个架构图,虽然简单,但是让自己脑子里时时记得架构图,是非常有必要的。因为架构级的分析,就是要胸怀架构,在看到一个问题点时,可以从架构图中立即反应出来问题的相关性。

上面这张图是自己脑子里的逻辑图,数据在网络中的流转并不是这样,而是像下图这样。

数据流是从压力机到应用服务器,应用服务器再到网络设备,再到数据库服务器;数据库把数据返回给应用服务器,应用服务器再通过网络设备给压力机。

如果把里面的Redis、ActiveMQ和MySQL的逻辑再细说明白,那么这个小小的应用都可以描述好一会。所以这里,我先大概描述一下,如果后面的分析中涉及到了相应的逻辑,再一点点加进来。

应用服务器只有一台,上面有两个Tomcat实例;数据库服务器有三个应用。混合场景中有四个业务,其中三个访问Tomcat1,第四个访问Tomcat2。

场景描述

有了场景大概的画像之后,我们再来看场景。根据测试工程师描述:

  1. 响应时间慢的,都是可视化页面,有不少图片、JS、CSS等静态资源。公网上是用CDN的,现在只测试内网的部分。静态资源已经做了压缩。
  2. 单业务测试的容量是可以满足要求的,但混合场景响应时间就长。系统资源用得并不多。
  3. 压力场景是300线程,Ramp-up period是1秒。
  4. Duration是72000。
  5. 各参数化都已经做了,参数化数据也合理。
  6. 测试环境都是内网。
  7. 服务器是CentOS,压力机是Win10。

既然这样,我们还是要看看系统的各个资源,再来判断方向。我在很多场合都强调证据链。对架构比较简单的应用来说,我们都不用再做时间的拆分了,直接到各主机上看看资源就好了。

瓶颈分析定位

根据我们之前画的架构图,我们从应用服务器、数据库服务器和压力数据分别定位一下。

  • 应用服务器

从前面的应用服务器资源来看,CPU使用率现在还不高,也基本都在us CPU(就是user消耗的CPU)上,比例也比较合理。

物理内存8G,还有3.5G。即使不多,对Java应用来说,也要先看JVM,只要不是page fault过多,我们可以先不用管物理内存。

网络资源接收900KB/s左右,发送11M左右。这样的带宽应该说是比较敏感的,因为对100Mbps和1000Mbps来说,我们要心里有一个数,一个是12.5MB(对应100Mbps),一个是125MB(对应1000Mbps),当和这样的带宽值接近的时候,就要考虑下是不是带宽导致的压力上不去。不过这里我们也不用先下定论。只是留个疑问在这里。

磁盘资源,基本上没有读写,很正常。

从Process列表中,也没看到什么异常数据。faults也都是min,major fault并没有。但在这个案例中,还部署了另一个监控工具,上面显示如下:

为什么这个Swapping要标黄呢?那肯定是过大了嘛。是的,你可以觉得swap过多。这个扣,我们也记在心里。在这里标红加粗敲黑板!

  • 数据库服务器

照样分析,CPU、内存、网络、磁盘、Process列表,并没看到哪里有异常的数据,连网络都只有500多k的发送。

这样的数据库资源状态告诉我们,它不在我们的问题分析主线上。接下来是压力数据。

  • 压力数据

这是JMeter中的聚合报告:

从上面这张图也能看出,响应时间确实挺长的,并且,300线程只有37的TPS,带宽总量10M左右。这个带宽倒是和应用服务器上的带宽使用量相当。关于这个带宽的判断请你一定注意,对于性能分析来说,带宽能不能对得上非常重要。比如,客户端接收了多少流量,服务端就应该是发出了多少流量。如果服务端发了很多包,但是客户端没有接收,那就是堵在队列上了。

既然其它的资源暂时没出现什么瓶颈。其实在这个时间里,如果是复杂的应用的话,我们最应该干的一件事情就是拆分时间。如下图所示:

这里我把时间拆为t1-t5,具体分析哪一段为什么消耗了时间。我们可以在Tomcat中加上%D和%F两个参数来记录request和response的时间。

在没有做这个动作之前,我们先把前面的扣解决一下。首先,带宽是不是受了100Mbps的限制?

一般来说,判断网络的时候,我们会有几个判断点。

首先是带宽的流量大小,也就是前面我们看到的11M左右的值。一般来说,100Mbps是指的bit per second,但是在应用层基本上都是byte,所以对100Mbps来说,是12.5MB。

其次是,全连接和半连接队列是否已经溢出?

我们通过SYNs to LISTEN sockets dropped来判断半连接队列是否溢出,通过times the listen queue of a socket overflowed来判断全连接队列是否溢出。

通过实时的查看,这两个值的增加并不多。所以这里不会是问题点。

最后是发送和接收队列是否堆积?

通过应用服务器上的send-Q(前面数第三列),可以看到服务器和压力机之间的的队列还是很长的,基本上每次查看都存在,这说明队列一直都有堆积。

我们再到压力机上看看带宽用了多少:

看这里也是用到了93Mbps,那么到这里我们就可以确定是网络问题导致的TPS上不去,响应时间增加,系统资源也用不上了。

和系统管理员确认宿主机的带宽后,被告知宿主机确实是100Mbps。

似乎这个分析到这里就可以结束了,直接把带宽加上再接着测试呗。但是,从项目实施的角度上说,这个问题,并不是阻塞性的。

为了把更多的性能问题提前找出来,现在我们先不下载静态资源,只发接口请求找下其他性能问题。这个带宽的问题,记一个bug就行了。

优化结果

我们将静态资源全都过滤掉之后,再次执行场景,结果是下面这样的。

JMeter压力数据:

应用服务器带宽:

数据库服务器带宽:

应用服务器网络队列:

应用服务器资源监控:

通过上面的结果可以看出:

  1. TPS可以达到221.5了,并且Received和Sent的字节加一起不到4MB。
  2. 应用服务器和数据库服务器的带宽都用到了近40Mbps,和JMeter结果也相当。
  3. 应用服务器上的网络队列也没有堆积。
  4. 应用服务器的CPU也已经能消耗到66%了,

当正在想通过过滤掉静态资源绕过带宽不足的现状来测试其他性能问题的时候,这时,Swap双向都标黄了。这时,性能测试工程师更纠结了,它为什么双向都黄了?CPU使用率才66%嘛。

其实,这两句话之间并没有什么关系,CPU使用率不管是多少,Swap该黄还是会黄。

这是为什么呢?这里卖个关子,在下一篇文章中,我们接着分析。

总结

带宽问题是性能分析中常见的问题之一,其难点就在于,带宽不像CPU使用率那么清晰可理解,它和TCP/IP协议的很多细节有关,像三次握手,四次挥手,队列长度,网络抖动、丢包、延时等等,都会影响性能,关键是这些判断点还不在同一个界面中,所以需要做分析的人有非常明确的分析思路才可以做得到。而且现在的监控分析工具中,对网络的判断也是非常薄弱的。

而Swap问题不能算是常见,只要出现,基本上就会很多人晕乎。解决的关键就是要明白Swap的原理,查到关联参数,然后就可以很快地定位了。

思考题

结合今天的内容,你能说一下网络的瓶颈如何判断吗?有哪几个队列?

欢迎你在评论区写下你的思考,也欢迎把这篇文章分享给你的朋友或者同事,一起交流一下。

精选留言

  • 土耳其小土豆

    2020-07-01 18:07:51

    高老师,网络队列的截图的具体命令能告知以下嘛?我想打印跟你那一样的
    作者回复

    netstat -naop就可以。

    2020-07-30 10:43:27

  • Geek_9e9d56

    2021-11-23 11:04:05

    高老师,应用和数据库服务器带宽截图的具体命令能否告知一下?谢谢
    作者回复

    我最常用的就是iftop。

    2021-11-27 00:49:18

  • Geek_Jean

    2021-09-02 17:44:56

    高老师,谢谢您给大家分享这么多的干货,真的受益非浅,但看完这讲后,我有3个问题没明白:
    1. 我有这样一个认知:服务端Send-Q如果有积压,那实时查看网络带宽的时候服务端的发送量和客户端的接收量不会对等。这个认知对吗?
    如果上面说的是对的,那我又有一个新问题:
    服务端网络资源接收 900KB/s 左右,发送 11M 左右;然后通过查看压力机上的网络接收流量可以看到是93Mbps,换算之后也就是11M左右,
    这么看服务端的发送量和客户端的接收量是一样的,带宽是对得上的。依据这样的推断服务端的Send-Q应该不会有积压才对。这个怎么理解呢?
    如果上面的认知不对:那我有另外一个新问题:
    实时查看服务端的时候Send-Q都有积压了,那说明这些数据还没有到达客户端,那客户端的接收量就不会接近服务端的发送量了。但实际上他们都是93Mbps.这是怎么回事呢?
    作者回复

    有积压时,发送方和接收方的值确实不会对等,但这个偏差很小,你可以查看一下发送方的发送缓冲区大小和内核限制的写缓冲区最大值、以及接收方的接收缓冲区大小和内核限制的读缓冲区大小。
    如果你可以在两边抓到同一时刻(记住是同一时刻)的网络带宽,那就会看到区别。

    不过我觉得你不用纠结这一点。因为这个队列要长期有值才说明阻塞严重,偶尔有值或间歇性有值是不用关心的。

    2021-09-03 09:21:33

  • Geek_237b86

    2020-03-31 16:40:15

    老师swapping标黄的是什么工具?
    作者回复

    spotlight。

    2020-03-31 21:45:26

  • 糯糯

    2021-04-30 01:20:42

    老师 有个问题,如果说要找到系统上限,是找到系统瓶颈呢,还是尽可能的压测至服务器资源沾满呢
    作者回复

    瓶颈是上限的绊脚石,得先解决,再把资源占满才有意义。

    2021-05-08 13:44:34

  • bettynie

    2020-04-13 09:43:31

    高老师,我们做内网测试时采用直连的方式,是不是可以更好的避免内网的网络问题,只考虑网卡的限制,这样可以把精力放在程序本身,先找出比较严重的性能问题再来考虑网络影响?
    作者回复

    如果有必要的话,可以这样做。只是在内网中,网络设备的背板吞吐都是很大的。你的应用有这么大的流量吗?

    2020-04-15 21:54:25

  • 大拇哥

    2020-02-21 12:19:21

    1)查看服务器发包数量,客户端接口数据包的量是不基本一致,如果出现明显的差别,可以基本确定客户端网络问题
    2)查看jmeter聚会报告上面客户端接口数据量是否已经接近宽带的限制
    队列:
    服务端消息发送队列
    客户端接收数据的队列
    服务端超时队列
    作者回复

    1,当网络有问题的时候,主要看队列,不用再对比流量了,因为已经没有意义了。
    2,对。

    2020-02-21 18:12:59

  • Geek_a8d2eb

    2021-02-27 15:40:58

    压测时在应用服务上执行命令netstat -naop,发现Recv-Q和send-Q都有间歇性的非0状态,5秒内就恢复0了。网上搜说可接受短暂的非0情况,短暂的Send-Q队列发送pakets非0是正常状态。请问这种说法靠谱么,观察tps和响应曲线也会出现相应的锯齿状
    作者回复

    短暂的非0确实是可能接受的。如果tps和响应时间跟网络队列相关,这就要有证据才可以了。那你需要的是拆分响应时间,看有没有在网络上消耗。

    2021-03-22 22:19:25

  • 😂

    2020-12-08 02:32:04

    老师,如何判断带宽不够呀?1.服务器接受和发送的流量接近或超过带宽,说明带宽不够?2.压力机接受和发送的流量接近或变过带宽,说明带宽不够?
    作者回复

    看队列。

    2020-12-08 19:55:13

  • nelson

    2020-05-11 00:14:15

    文稿中提及“综上现象就是,单业务场景执行起来并不慢,但是一混合起来就很慢,应用服务器和数据库服务器的系统资源使用率并不高。请问慢在哪?”
    经过一系列分析,没有给出单业务为什么不慢,如果是带宽问题,单业务也一定会慢
    作者回复

    这里提的单业务不慢,是因为对于同样的带宽来说,单业务的TPS是没有业务限定的。而混合场景中会有业务目标限定。

    2020-05-29 16:05:51

  • 月亮和六便士

    2020-04-08 21:13:33

    为什么同一个服务器,同一个环境,用Nmon监控,显示swap正常,page fault 也很小,用spotlight监控,swap就黄了,不科学啊。
    作者回复

    你说的小是多少?有没有数据发出来看看?

    2020-04-09 10:16:29

  • Geek_454a8f

    2020-02-26 14:12:06

    tomcat使用什么监控的
    作者回复

    本例中没分析tomcat,一开始的的监控图是个老旧的工具probe。

    2020-02-26 18:32:42

  • yayiyaya

    2023-07-18 16:08:13

    网络瓶颈的判断:
    简单的方法,就是在这段链路中传输大文件, 查看传输速率,判断带宽;
    如果带宽较大的情况下, 服务网络性能还是达到瓶颈,使用tcpdump 在两端进行抓包; 查看数据包是否存在乱序,重传、拥塞的情况(网络性能不佳的情况,往往会出现这样的现象)
    作者回复

    记得看队列。

    2023-11-08 21:27:02

  • Geek_588072

    2022-10-15 22:45:38

    老师和同学好。
    想请教一个简单的问题,"应用服务器网络队列"那张图的记录是用什么命令得到的?
    作者回复

    netstat

    2022-10-19 22:13:20

  • 徐峥

    2022-03-24 18:32:29

    高老師,您好。查看发送和接收队列是否堆积的命令是什麽?
    作者回复

    netstat。

    2022-03-30 08:44:31

  • Allister🏅

    2021-07-22 08:21:25

    高老师,第一张资源监控(cpu,内存,网络等)用什么看的呢?
    作者回复

    你是说nmon吗?

    2021-07-22 14:40:37

  • jy

    2021-07-12 15:25:59

    请问下,应用服务器上的 send-Q那个图,是应用listen状态还是非listen状态的截图?
    作者回复

    建立连接的状态。

    2021-07-14 10:35:40

  • Geek_a8d2eb

    2021-02-22 11:47:22

    高老师,带宽分析那里没看懂,应用服务器发送约11MB,约等于88Mbqs。压力机接收的带宽是93Mbqs。怎么就是带宽的问题呢,发出的比接收的还小呀?
    作者回复

    因为数据包拆分成大小不一的包之后是很难达到线性的呀。

    2021-03-22 22:25:20

  • Geek_ed7255

    2020-04-02 22:49:32

    老师,内网和外网压测有什么区别
    作者回复

    主要就是网络。没其他区别。

    2020-04-04 11:16:52

  • 餘生

    2020-03-28 10:35:37

    对于性能分析来说,带宽能不能对得上非常重要。比如,客户端接收了多少流量,服务端就应该是发出了多少流量。如果服务端发了很多包,但是客户端没有接收,那就是堵在队列上了。

    关于这一段话,我想请问下,为什么没有提到客户端发出请求的流量大于服务端接收的情况?这种情况需要考虑吗?如果要考虑的话,通常会出现哪几种现象,要如何分析
    作者回复

    对于网络来说,不分客户端,服务端。只要分发送和接收端就可以。
    并且,也不会出现某一端发的大,另一端接的少的这种情况,接收端接不了,发送端肯定就排队去了。
    所以,你说的其实是一种现象。

    2020-03-29 16:04:06