[TOC]算法
性能分析三板斧之一:缓存
【统计->捕获文件属性】 Statistics -> Summary,查看文件属性信息,如平均速度、包大小、包数等等安全
判断流量高低峰、是否过载bash
性能分析三板斧之二:服务器
【分析->专家信息】 Wireshark ->Analyze -> Expert Infos -> Notes,查看抓包的统计信息微信
查看是否有Notes、Warnings、errors之类的信息,看看是否有相关警告和错误,判断网络质量、重传乱序等网络
性能分析三板斧之三:tcp
【统计->服务响应时间】 statistics -> Service Response Time -> xxxxx(如:ONC-RPC -> Program:NFS)工具
查看各项操做的服务响应时间,判断是否过载性能
Edit->Preferences->Protocols->TCP,勾选 Relative Sequence Numbers
启用以前就是相对值了。
Statistics -> TCP StreamGraph -> TCP Sequence Graph(Stevens)
查看数据传输状况,如传输的是否均匀、是否有TCP Zero Windows之类的
字段含义就是wireshark的一些提示信息,也就是wireshark抓包的一些info信息,这些提示信息都是Info这一栏中体现。
若是某个包被标记提示[Packer size limited during caputre]
,说明这个包没有抓全,能够进一步查看下面的frame信息。通常这个状况是抓包的姿式不对。某些操做系统中,tcpdump默认只抓取每一个帧的前96个字节,所以tcpdump抓包的时候,能够经过 -s参数指定要抓取的字节数
若是wireshark发现被Ack的那个包没有抓到,就会提示[TCP ACKed unseen segment]
,不过这个提示大部分状况均可以忽略。由于大都状况下,刚开始抓包的时候,都是只抓到了后面的Ack而没有抓到前面的ACK
TCP数据传输中,除了三次握手和四次握手以外,同一台机器发出的数据段应该是连续的,即后一个包的Seq等于前一个包的Seq+Len,正确状况都应该是这样;若是发现后一个包的Seq大于前一个包的Seq+Len,那么就说明中间丢了一段数据,若是丢失的数据在整个网络包中都找不到,wireshark就会提示[TCP Previous segment not captured]
,
出现这种状况的两个可能性:
TCP数据传输中,除了三次握手和四次握手以外,同一台机器发出的数据段应该是连续的,即后一个包的Seq等于前一个包的Seq+Len,正确状况都应该是这样;或者说后一个包的Seq应该会大于等于前一个包的Seq+Len,若是wireshark发现后一个包的Seq小于前一个包的Seq+Len,那么就认为是乱序了,就会提示[TCP Out-of-Order]
。
通常而言,小跨度的乱序影响不大,若是是大跨度的乱序则会致使快速重传。举例以下,若是一个包的顺序是一、二、三、四、5被打乱成二、一、三、四、5则属于小跨度乱序,影响不大;若是被打乱成二、三、四、五、1,则会触发足够多的Dup ACK,从而致使1号包的重传。
当乱序或者丢包发生时,接收方就会收到一些Seq号比指望值大的包,TCP协议每收到一个这种包就会ACK一次指望的Seq值,经过这个方式告知发送方,所以就产生了一些重复的Ack。Wireshark抓到这些重复的Ack就会提示[TCP Dup ACK]
.
当发送方连续收到3个或者以上[TCP Dup ACK]
时,就意识到以前发的包可能丢了,因而根据RFC的规定就会开始快速重传。[TCP Dup ACK]
是接收方回应给发送方的,所以发送方就可以感知到并当连续收到3个以上的时候就开启快速重传。
快重传算法规定,发送方只要一连收到3个重复确认就应当当即重传对方还没有收到的报文段,而没必要继续等待设置的重传计数器时间到期。
若是一个包真的丢了,又没有后续包能够在接收方触发[Dup Ack],那么就不会开启快速重传,这种状况发送方只能等到超时后再发送重传,超时重传的包就会被wireshark标记并提示[TCP Retransmission]
TCP 超时与重传应该是 TCP 最复杂的部分之一,超时重传是 TCP 保证可靠传输的基础。当 TCP 在发送数据时,数据和 ack 都有可能会丢失,所以,TCP 经过在发送时设置一个定时器来解决这种问题。若是定时器溢出尚未收到确认,它就重传数据。关键之处就在于超时和重传的策略,须要考虑两方面:
在 Linux 较高的内核版本中,好比 3.15 中,已经有了至少 9 个定时器:超时重传定时器,持续定时器,ER延迟定时器,PTO定时器,ACK延迟定时器,SYNACK定时器,保活定时器,FIN_WAIT2定时器,TIME_WAIT定时器。
TCP包中“win=xxx”表明接收窗口的大小,表示这个包的发送方当前还有多少缓冲区能够接受数据。当wireshark发行一个包中的“win=0”时,就会标记提示[TCP zerowindow]
,表示缓冲区已经满了,没法再接收数据了。
通常的,在缓冲区满以前,窗口大小应该是逐渐减少的过程。
若是一个包的发送方已经把对方所声明的接收窗口大小耗尽了,就会被wireshark标记为[TCP window Full]
。好比某一端在握手时声明本身的接收窗口只有65535,也就意味着对端最多只能给他发送65535字节的数据而无需确认,即“在途字节数”最多只能是65535,当wireshark计算出对端已经有65535字节未被确认时,就会发生这个提示。
[TCP window Full]和上面的[TCP zerowindow]比较容易混淆,前者表示这个包的发送方暂时没有办法再发送数据了;后者表示这个包的发送方没有办法再接收数据了;二者都会意味着要暂停数据传输
只有在Edit->Preferences->Protocols->TCP菜单里启用了Allow sub dissector to reassemble TCP streams
后,才有可能收到这个提示。这个表示能够把属于同一个应用层PDU的TCP包虚拟的集中起来
只有在Edit->Preferences->Protocols->TCP菜单里关闭了Allow sub dissector to reassemble TCP streams
后,才有可能收到这个提示。
(Fragment reasembly time execeeded)表示这个包的发送方以前收到了一些分片,可是因为某些缘由致使迟迟没法组装起来。
好比传输过程当中有一些分片被丢包了,那么接收方就没法组装起来,而后就经过这个ICMP的方式告知发送方
ICMP是(Internet Control Message Protocol)Internet控制报文协议。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络自己的消息。这些控制消息虽然并不传输用户数据,可是对于用户数据的传递起着重要的做用。
在TCP层,有个FLAGS字段,这个字段有如下几个标识:SYN, FIN, ACK, PSH, RST, URG.
抓包显示的控制字段形态以下:
[SYN] : 创建链接、发起包 [FIN] : 关闭链接、结束包 [PSH] : DATA数据传输 [ACK] : ACK回应 [RST] : RESET、链接重置
另外两个经常使用字段:
[Len] :数据包长度 [Seq] :数据包序列号
ACK是可能与SYN,FIN等同时使用的,好比SYN和ACK可能同时为1,它表示的就是创建链接以后的响应,若是只是单个的一个SYN,它表 示的只是创建链接
当出现FIN包或RST包时,咱们便认为客户端与服务器端断开了链接 当出现SYN和SYN+ACK包时,咱们认为客户端与服务器创建了一个链接
对应http而言,通常就是request->reponse,一问一答。但对应TCP而言,并不必定每一个包都会ACK。TCP的ACK是一种累积的ACK,也就是表示在我这个ACK以前的全部其余ACK都已经确认收到了。
好比,97号包的ACK=65701,96号包的Seq+Len=64273+1428=65701,那么就是表示97号的ACK是对96号的回应,也就是96号以前的其余没有被显示ACK的包,其实都已经经过97号包ACK了,这样发送方也就知道了在96号以前发出去的全部包对方都已经收到并ACK了。
MSL(Maximum Segment Lifetime),表示“报文最大生存时间”,是全部报文都遵循的在网络上存在的最长时间,超过这个时间报文将被丢弃
TTL(Time to live),表示生存时间,是ip头的一个域,生存时间是由源主机来设置一个初始值,但TTL不是存的具体时间,而是表示能够通过的最大路由数。
Time to live: 62
RTT(round-trip time),表示客户到服务器往返所花时间,TCP含有动态估算RTT的算法
Protocol = ARP Source 和 Destination 都是MAC地址格式如 00:60:48:ff:12:31
抓包分析中,若是网络不通,发出去收不到ACK等等之类的,要再进一步看看每一个包的MAC地址是否正确,反之有多个MAC地址致使的一些问题
三次握手协议
抓包数据,如何判断一个包是上一个包的回包呢?根据TCP协议,下一个包的Ack的值若是等于上一个包的Seq + Len,则表示是其回包
三次握手的时候会相互声明各自的MSS
TCP四次挥手协议
正常而言,都会有这样的四次挥手,可是若是有延迟确认,那么四次挥手就变成了3次挥手,省掉了四次挥手中的第二个包
一些实战经验告诉咱们,Wireshark ->Analyze -> Expert Info -> Notes
统计中的重传率若是超过了0.1%,就须要采起一些措施了。可是现实网络环境下,要低于0.01%的重传是基本不可能的。
是为了减小广域网的小分组数目,从而减少网络拥塞的出现;
该算法要求一个tcp链接上最多只能有一个未被确认的未完成的小分组,在该分组ack到达以前不能发送其余的小分组,tcp须要收集这些少许的分组,并在ack到来时以一个分组的方式发送出去;其中小分组的定义是小于MSS的任何分组;
该算法的优越之处在于它是自适应的,确认到达的越快,数据也就发哦送的越快;而在但愿减小微小分组数目的低速广域网上,则会发送更少的分组;
if there is new data to send
if the window size >= MSS and available data is >= MSS
send complete MSS segment now
else
if there is unconfirmed data still in the pipe
enqueue data in the buffer until an acknowledge is received
else
send data immediately
end if
end if
end if
复制代码
若是tcp对每一个数据包都发送一个ack确认,那么只是一个单独的数据包为了发送一个ack代价比较高,因此tcp会延迟一段时间,若是这段时间内有数据发送到对端,则捎带发送ack,若是在延迟ack定时器触发时候,发现ack还没有发送,则当即单独发送;
延迟ACK好处:
(1) 避免糊涂窗口综合症; (2) 发送数据的时候将ack捎带发送,没必要单独发送ack; (3) 若是延迟时间内有多个数据段到达,那么容许协议栈发送一个ack确认多个报文段;
试想以下典型操做,写-写-读,即经过多个写小片数据向对端发送单个逻辑的操做,两次写数据长度小于MSS,当第一次写数据到达对端后,对端延迟ack,不发送ack,而本端由于要发送的数据长度小于MSS,因此nagle算法起做用,数据并不会当即发送,而是等待对端发送的第一次数据确认ack;这样的状况下,须要等待对端超时发送ack,而后本段才能发送第二次写的数据,从而形成延迟;
使用TCP套接字选项TCP_NODELAY能够关闭套接字选项;
以下场景考虑关闭Nagle算法:
(1) 对端不向本端发送数据,而且对延时比较敏感的操做;这种操做无法捎带ack; (2) 如上写-写-读操做;对于此种状况,优先使用其余方式,而不是关闭Nagle算法:
TCP和UDP的区别如TCP是可靠的、UDP是不可靠的,可是实际中的表现是何为可靠?何为不可靠?具体协议的ACK有何区别?
无论对于TCP仍是UDP,均可能会被分片,这是因为以太网的MSS决定的;不一样在于分片传输的处理:
语音通话的场景在于不能接受延迟,可是能够接受音质稍差。这样的话,UDP传输的时候,若是有些包丢失,应用层能够选择忽略并继续传输其余包,丢到一些包只会影响到音质,可是保证了流畅性。TCP而言,会重传每一个包,只要丢包就重传,这样就会致使有必定的延迟,在语音中若是有延迟则并不可取。
所以,TCP和UDP,各自有各自的适合场景。 语音、视频中,UDP更合适,像声网、linphone等都是UDP去处理音视频。 基础、核心协议交互中必须采用TCP。
TCP在传输过程都须要往返时间来确认也就是ACK,而UDP则无需确认,那么UDP的效率必定比TCP高吗?这个是不必定的,虽然UDP能够一直往外不停的发包,不用等待ACK;可是TCP有发送窗口的存在,若是发送窗口小,并无占满带宽,那么确定受到往返时间的约束使得效率稍低,可是若是只要窗口足够大而且合适,跑满带宽,那么TCP也是能够不受往返时间的约束而源源不断的传输数据。
举例:马路上只有一辆车来回跑去拉货,回程过程至关于空跑(回程至关于TCP的ACK),这样TCP的效率固然低。可是若是在不拥塞的状况下,尽可能提升车辆数量,是的马路上的车被恰好充满,这样整体的传输效率提升了,而且回程的ACK也不受影响。
分组交换,把大的数据分割成小包,这样能够实现链路共享,而不至于由于某一方阻塞全部。既然要分割成小包,那么必然要肯定一个最大的包大小,这个就是MTU(Maximum Transmission Unit)最大传输单位,值为1500字节。若是除去20个字节的包头结构,那么一个IP包最大的包大小为1500-20=1480字节。若是要传输的数据块超过1480字节,那么网络层就会将其分片处理,封装为多个网络包传输。对于TCP而言,TCP协议层会主动把数据分红小段后再交给网络层,TCP的最大分段大小称之为MSS(Maximum Segment Size),这个MSS被设置为MTU减去IP头和TCP头以后的大小,这样恰好能够知足一个MTU。由于UDP没有MSS的概念,所以就只能交给网络层去处理分片了。
可是须要注意的是,目前有些网络是Jumbo Frame(巨帧)或者PPPOE这样的设备,那么他们的MTU则不是1500字节。目前发送方并无一个好的机制来肯定最佳分片大小,应该尽可能使得网络中的设备的MTU保持一致。若是网络中的设备的MTU不一致,那么TCP协议如何适配MTU呢?咱们知道TCP建连的时候必需要先进行三次握手,TCP在前两个握手包中会相互声明本身的MSS。若是client端声明本身的MSS=8960(巨帧),server端申明本身的MSS=1460,那么client在三次握手后就知道了server端的MSS,所以当client想要发送大于server端MSS的包的时候就会主动将本身的MSS下降为server端的MSS大小,从而适配接收方的MTU,可见,TCP协议层作了很是多的优化和处理
既然有分片,那么接收方必然要进行分片重组,经过抓包工具能够得知,分片的每一个包都包含了off=xxx,ID=xxx
这样的信息,接收方会把ID相同的分片按照off偏移量进行重组。那么接收方又如何得知那个包才是最后的分片呢?而后何时开始重组呢?这里就在于最后一个分片包有一个特殊的Flag,叫More fragment = 0
,抓包中的表现形式是..0. ... = More fragment: Not set
,这个就表示它是最后一个分片,而后能够开始重组包了。若是是其余分片包,形如..1. ... = More fragment: set
则表示接收方须要缓存,等待其余分片传输完成
若是client端的MTU=9000,server端的MTU=1500,那么当client请求server端的时候,client的包通过路由器时候,要么就被丢包,要么就被分片。若是这个巨帧包在网络层携带了DF(Don't fragment)标志则被丢弃(设置则表示不容许分片),若是没有设置则进行分片传输。须要注意的是,这种状况下若是丢包了重传仍是会被丢弃,就成了黑洞了。
测试中,能够经过ping命令模拟这样的状况:
成功:
ping xxx.xxx.xxx.xxx -l 1472 -f -n 1
失败:
ping xxx.xxx.xxx.xxx -l 1473 -f -n 1
复制代码
-f 参数表示设置DF标志 -l 参数表示请求字节
当请求字节设置为1472的时候,由于ICMP头部为8字节、IP头为20字节,所以1472+8+20=1500,恰好是一个MTU,所以能够ping成功。可是第二个1473+8+20=1501字节超过MTU了,又由于设置了DF标志表示不容许分片,所以传输失败,通常这样的状况下,路由器会回复Packet needs to be fragmented but DF set
。
抓包的时候,若是发现一直重传,某个某些相对较大的包(查看Len值)才重传,那么能够经过ping xxx.xxx.xxx.xxx -l [Len] -f
值进行测试验证,经过这个ping指定的[Len]的大小变化来寻得规律,可能就会发现网络上某个设备的MTU并不是1500,这样致使了超过这个就重传的现象。
client 和 server端直接必定有交换机、路由器等设备,若是server端是万兆网卡,client端是千兆网卡,就有可能使得server端发送过快致使数据堵在交换机上,从而交换机在堵满以后发生丢包。 可是通常而言,server端的带宽本应该要大于client端才算合理,为了不拥塞,所以须要有一种流控机制,容许交换机在过载时告知server端放慢速度或者暂停传输。
有一种“暂停帧”,就可以知足这样的需求:当交换机的缓冲区即将被填满时发送给server端一个暂停帧,当server端等待一下子再发,这样就能够避免溢出丢包,也避免丢包后的重传。server端等待多久则由暂停帧中的pause_time指定,这样server端在等待pause_time后才会开始继续发送。固然交换机还能够给server端发送一个pause_time=0的暂停帧,告知server端,我已经消化完了,能够当即发送了。
注意,这的流控和TCP的流控是不同的
经过wireshark排查问题,须要分析网络包,在网络包中寻找一些线索,而后根据网络协议做出推断,接着就是一个一个去否认,而后最终找到问题所在
须要可以理解底层TCP协议,要可以清楚每个字段表示的含义
要善用Wireshark的一些统计、分析工具;过滤器等
发送发抓包和接收抓包是有极大区别的
要善用“三板斧“的操做流程和步骤去分析问题
【"欢迎关注个人微信公众号:Linux 服务端系统研发,后面会大力经过微信公众号发送优质文章"】