转自:http://perthcharles.github.io/2015/11/10/wiki-netstat-proc/
netstat -st输出的两个重要信息来源分别是/proc/net/snmp和/proc/net/netstat
本文将分类整理这些counterd的含义以及一些注意事项。
在整理的过程中,发现Rover Yu前辈已经
对这些counter做过详细的整理。关于Rover Yu前辈的整理请查看参考资料中的前三篇。
本着不重复造轮子的原则。本文将尽量遵循以下原则,以期从不同的角度呈现对这些counter的理解。
a. 分类整理:根据涉及的不同<span class="type">TCP细节,对counter做更细致的分类
b. 结合sysctl配置:强调sysctl配置与counter之间的关联
<span class="built_in">c. 强调异常:哪些counter出现非零值,往往就意味着出现了值得关注的问题
d. 信息抽取: 如何从counter中获取有价值的信息
e. 仅关注<span class="type">TCP相关计数器
</span></span></span>
类别涉及counters 常量 RtoAlgorithm、RtoMin、RtoMax、MaxConn 建连统计 ActiveOpens、PassiveOpens、AttemptFails、CurrEstab、EstabResets 数据包统计 InSegs、OutSegs、RetransSegs、InErrs、OutRsts、InCsumErrors、EmbryonicRsts syncookies功能 SyncookiesSent、SyncookiesRecv、SyncookiesFailed TIME_WAIT回收 TW、TWRecycled、TWKilled、TCPTimeWaitOverflow RTO次数 TCPTimeouts、TCPSpuriousRTOs、TCPLossProbes、TCPLossProbeRecovery、
TCPRenoRecoveryFail、TCPSackRecoveryFail、
TCPRenoFailures、TCPSackFailures、
TCPLossFailures Retrans数量 TCPFastRetrans、TCPForwardRetrans、
TCPSlowStartRetrans、TCPLostRetransmit、
TCPRetransFail FastOpen TCPFastOpenActive、TCPFastOpenPassive、
TCPFastOpenPassiveFail、TCPFastOpenListenOverflow、
TCPFastOpenCookieReqd MD5 TCPMD5NotFound、TCPMD5Unexpected DelayedACK DelayedACKs、DelayedACKLocked、DelayedACKLost、
TCPSchedulerFailed DSACK TCPDSACKOldSent、TCPDSACKOfoSent、
TCPDSACKRecv、TCPDSACKOfoRecv、
TCPDSACKIgnoredOld、TCPDSACKIgnoredNoUndo Reorder TCPFACKReorder、TCPSACKReorder、
TCPRenoReorder、TCPTSReorder Recovery TCPRenoRecovery、TCPSackRecovery、
TCPRenoRecoveryFail、TCPSackRecoveryFail Abort TCPAbortOnData、TCPAbortOnClose、
TCPAbortOnMemory、TCPAbortOnTimeout、
TCPAbortOnLingerTCPAbortFailed
|reset相关 | |
|内存prune | PruneCalled、RcvPruned、OfoPruned、
TCPMemoryPressures |
|PAWS相关 | PAWSPassive、PAWSActive、PAWSEstab |
|Listen相关 | ListenOverflows、ListenDrops |
|undo相关 | TCPFullUndo、TCPPartialUndo、
TCPDSACKUndo、TCPLossUndo |
|快速路径与慢速路径 | TCPHPHits、TCPHPHitsToUser、
TCPPureAcks、TCPHPAcks |
这些常量是Linux3.10中的默认值,仅在升级了内核版本时才需要关心一下这些值的变化。
<span class="label">RtoAlgorithm:
默认为<span class="number">1,RTO算法与RFC2698一致
<span class="label">RtoMin:
默认值为HZ/<span class="number">5,即<span class="number">200ms
<span class="label">RtoMax:
默认值为<span class="number">120HZ,即<span class="number">120s
<span class="label">MaxConn:
协议栈本身并不会限制TCP连接总数,默认值为-<span class="number">1.
</span></span></span></span></span></span></span></span></span></span>
这些统计值中,只有CurrEstab反应的是系统当前状态,而其他值则是反应的历史状态
同时需要注意的是,这些计数器将ESTABLISHED和CLOSE-WAIT状态都作为当前连接数。
可以这么理解:这两个状态都以为这local=>peer方向的连接未被关闭
ActiveOpen<span class="variable">s:
主动建连次数,CLOSE => SYN-SENT次数
PassiveOpen<span class="variable">s:
被动建连次数,RFC原意是LISTEN => SYN-RECV次数,但Linux选择在三次握手成功后才加<span class="number">1
AttemptFail<span class="variable">s:
建连失败次数
EstabReset<span class="variable">s:
连接被reset次数,ESTABLISHED => CLOSE次数 + CLOSE-WAIT => CLOSE次数
CurrEsta<span class="variable">b:
当前TCP连接数,ESTABLISHED个数 + CLOSE-WAIT个数
</span></span></span></span></span></span>
这些统计值也是历史值,独立的来看意义并不大。一般可统计一段时间内的变化,关注以下几个指标
a. TCP层的重传率: ΔRetransSegs / ΔOutSegs — 越小越好,如果超过20%(这个值根据实际情况而定)则应该引起注意
b. Reset发送频率: ΔOutRsts / ΔOutSegs — 越小越好,一般应该在1%以内
c. 错误包占比: ΔInErrs / ΔInSegs — 越小越好,一般应该在1%以内,同时由checksum导致的问题包应该更低
InSeg<span class="variable">s:
收到的数据包个数,包括有错误的包个数
OutSeg<span class="variable">s:
发送的数据包个数
RetransSeg<span class="variable">s:
重传的包个数
InErr<span class="variable">s:
收到的有问题的包个数
OutRst<span class="variable">s:
发送的带reset标记的包个数
InCsumError<span class="variable">s:
收到的checksum有问题的包个数,InErrs中应该只有*小部分*属于该类型
EmbryonicRst<span class="variable">s:
在SYN-RECV状态收到带RST/SYN标记的包个数
</span></span></span></span></span></span></span>
syncookies一般不会被触发,只有在tcp_max_syn_backlog队列被占满时才会被触发
因此SyncookiesSent和SyncookiesRecv一般应该是0。
但是SyncookiesFailed值即使syncookies机制没有被触发,也很可能不为0。
这是因为一个处于LISTEN状态的socket收到一个不带SYN标记的数据包时,就会调
用cookie_v4_check()尝试验证cookie信息。而如果验证失败,Failed次数就加1。
SyncookiesSen<span class="variable">t:
使用syncookie技术发送的syn/ack包个数
SyncookiesRecv
收到携带有效syncookie信息包个数
SyncookiesFailed
收到携带无效syncookie信息包个数
</span>
注: syncookies机制是为应对synflood攻击而被提出来的。
TIME-WAIT状态是TCP协议状态机中的重要一环,服务器设备一般都有非常多处于TIME-WAIT状态的socket
如果是在主要提供HTTP服务的设备上,TW值应该接近TcpPassiveOpens值。
一般情况下,sysctl_tcp_tw_reuse和sysctl_tcp_tw_recycle都是不推荐开启的。这里解释了为什么。
所以TWKilled和TWRecycled都应该是0。
同时TCPTimeWaitOverflow也应该是0,否则就意味着内存使用方面出了大问题。
TW:
经过正常的TCP_TIMEWAIT_LEN(60s)结束TW状态的socket数量
TWKilled:
经过更短的时间结束TW状态的socket数量。
只有在net.ipv4.tcp_tw_recycle开启时,调度TW timer时才可能用更短的timeout值。
TWRecycled:
Port从TIMEWAIT socket中复用的次数。
只有在sysctl_tcp_tw_reuse开启时,才可能加<span class="number">1
郁闷的是上面两个counter的命名与sysctl的命名真是超级不一致啊。囧<span class="keyword">...
TCPTimeWaitOverflow:
如果没有内存分配TIME-WAIT结构体,则加<span class="number">1
</span></span></span>
RTO超时对TCP性能的影响是巨大的,因此关心RTO超时的次数也非常必要。
当然3.10中的TLP机制能够减少一定量的TCPTimeouts数,将其转换为快速重传。
关于TLP的原理部分,可参考我的这篇wiki。
<span class="label">TCPTimeouts:
RTO timer第一次超时的次数,仅包含直接超时的情况
<span class="label">TCPSpuriousRTOs:
通过F-RTO机制发现的虚假超时个数
<span class="label">TCPLossProbes:
Probe Timeout(PTO)导致发送Tail Loss Probe (TLP)包的次数
<span class="label">TCPLossProbeRecovery:
丢失包刚好被TLP探测包修复的次数
</span></span></span></span>
这些计数器统计的重传包,都不是由于RTO超时导致进行的重传
如果结合RetransSegs统计来看,如果这些非RTO导致的重传占比较大的话,也算是不幸中的万幸。
另外LostRetransmit的数量应该偏低比较好,重传包如果都大量被丢弃,则真的要注意了。
<span class="label">TCPLostRetransmit:
丢失的重传SBK数量,没有TSO时,等于丢失的重传包数量
<span class="label">TCPFastRetrans:
成功快速重传的SKB数量
<span class="label">TCPForwardRetrans:
成功ForwardRetrans的SKB数量,Forward Retrans重传的序号高于retransmit_high的数据
TODO: retransmit_high目前的理解是被标记为lost的SKB中,最大的end_seq值
<span class="label">TCPSlowStartRetrans:
成功在Loss状态发送的重传SKB数量,而且这里仅记录非RTO超时进入Loss状态下的重传数量
目前找到的一种非RTO进入Loss状态的情况就是:tcp_check_sack_reneging()函数发现
接收端违反(renege)了之前的SACK信息时,会进入Loss状态
<span class="label">TCPRetransFail:
尝试FastRetrans、ForwardRetrans、SlowStartRetrans重传失败的次数
</span></span></span></span></span>
TCP FastOpen(TFO)技术是Google提出来减少三次握手开销的技术,
核心原理就是在第一次建连时server计算一个cookies发给client,之后client向
server再次发起建连请求时就可以携带cookies信息验明正身。如果cookies验证通过,
server可以不等三次握手的最后一个ACK包就将client放在SYN包里面的数据传递给application layer。
在3.10内核中,TFO由sysctl_tcp_fastopen开关控制,默认值为0(关闭)。
而且sysctl_tcp_fastopen目前也是推荐关闭的,因为网络中有些middlebox会丢弃那些带有不认识的option的SYN包.
所以正常情况下这些值也应该都是0,当然如果收到过某些不怀好意带TFO cookies信息的SYN包,
TCPFastOpenPassive计数器就可能不为0。
<span class="label">TCPFastOpenActive:
发送的带TFO cookie的SYN包个数
<span class="label">TCPFastOpenPassive:
收到的带TFO cookie的SYN包个数
<span class="label">TCPFastOpenPassiveFail:
使用TFO技术建连失败的次数
<span class="label">TCPFastOpenListenOverflow:
TFO请求数超过listener queue设置的上限则加<span class="number">1
<span class="label">TCPFastOpenCookieReqd:
收到一个请求TFO cookies的SYN包时加<span class="number">1
</span></span></span></span></span></span></span>
TCP MD5 Signature选项是为提高BGP Session的安全性而提出的,详见RFC 2385。
因此内核中是以编译选项,而不是sysctl接口来配置是否使用该功能的。
如果内核编译是的CONFIG_TCP_MD5SIG选项未配置,则不会支持TCPMD5Sig,下面两个计数器也就只能是0
<span class="label">TCPMD5NotFound:
希望收到带MD5选项的包,但是包里面没有MD5选项
<span class="label">TCPMD5Unexpected:
不希望收到带MD5选项的包,但是包里面有MD5选项
</span></span>
DelayedACK是内核中默认支持的,但即使使用DelayedACKs,每收到两个数据包也
必须发送一个ACK。所以DelayedACKs可以估算为发送出去的ACK数量的一半。
同时DelayedACKLocked反应的是应用与内核争抢socket的次数,
如果占DelayedACKs比例过大可能就需要看看应用程序是否有问题了。
<span class="label">DelayedACKs:
尝试发送delayed ack的次数,包括未成功发送的次数
<span class="label">DelayedACKLocked:
由于usr锁住了sock,而无法发送delayed ack的次数
<span class="label">DelayedACKLost:
TODO 暂时不理解准确含义
<span class="label">TCPSchedulerFailed:
如果在delay ack处理函数中发现prequeue还有数据,就加<span class="number">1。
数据放到prequeue,就是想user能尽快处理。如果任由数据,
则可能user行为调度效果不好
这个值应该非常接近于零才正常
</span></span></span></span></span>
该类型计数器统计的是收/发DSACK信息次数。
DSACKOldSent + DSACKOfoSent可以当做是发送出的DSACK信息的次数,而且概率上来讲
OldSent应该占比更大。
同理DSACKRecv的数量也应该远多于DSACKOfoRecv的数量。
另外DSACK信息的发送是需要sysctl_tcp_dsack开启的,如果发现sent两个计数器为零,则要检查一下了。
一般还是建议开启dsack选项
<span class="label">TCPDSACKOldSent:
如果收到的重复数据包序号比rcv_nxt(接收端想收到的下一个序号)小,则增加oldsent
<span class="label">TCPDSACKOfoSent:
如果收到的重复数据包序号比rcv_nxt大,则是一个乱序的重复数据包,增加ofosent
<span class="label">TCPDSACKRecv:
收到的old dsack信息次数,判断old的方法:dsack序号小于ACK号
<span class="label">TCPDSACKOfoRecv:
收到的Ofo dsack信息次数
<span class="label">TCPDSACKIgnoredOld:
当一个dsack block被判定为无效,且设置过undo_marker,则加<span class="number">1
<span class="label">TCPDSACKIgnoredNoUndo:
当一个dsack block被判定为无效,且未设置undo_marker,则加<span class="number">1
</span></span></span></span></span></span></span></span>
当发现了需要更新某条TCP流的reordering值(乱序值)时,以下计数器可能被使用到。
不过下面四个计数器为互斥关系,最少见的应该是TCPRenoReorder,毕竟sack已经被
广泛部署使用了。
TODO: 什么情况下能准确的判断出要更新reorder值呢?
<span class="label">TCPTSReorder:
如果是被一个partial ack确认后需要更新reorder值,则加<span class="number">1
这个地方取个TS的名字,还真是费解。不知道是什么的缩写表示了partial ack的含义。
<span class="label">TCPRenoReorder:
如果被不支持SACK的dupack确认后,需要更新reorder值,则加<span class="number">1
<span class="label">TCPFACKReorder:
如果在需要更新时判断支持FACK,则加<span class="number">1
<span class="label">TCPSACKReorder:
如果仅支持SACK,则该计数器加<span class="number">1
</span></span></span></span></span></span></span></span>
In <span class="operator">the <span class="keyword">case <span class="operator">of multiple packets dropped <span class="built_in">from <span class="operator">a single window <span class="operator">of data,
<span class="operator">the <span class="keyword">first <span class="built_in">new information available <span class="built_in">to <span class="operator">the sender comes when <span class="operator">the
sender receives <span class="operator">an acknowledgment <span class="keyword">for <span class="operator">the retransmitted packet (that
is, <span class="operator">the packet retransmitted when fast retransmit was <span class="keyword">first entered).
If there is <span class="operator">a single packet drop <span class="operator">and no reordering, <span class="keyword">then <span class="operator">the
acknowledgment <span class="keyword">for this packet will acknowledge all <span class="operator">of <span class="operator">the packets
transmitted <span class="keyword">before fast retransmit was entered. However, <span class="keyword">if there
are multiple packet drops, <span class="keyword">then <span class="operator">the acknowledgment <span class="keyword">for <span class="operator">the
retransmitted packet will acknowledge some but <span class="operator">not all <span class="operator">of <span class="operator">the packets
transmitted <span class="keyword">before <span class="operator">the fast retransmit. We call this acknowledgment
<span class="operator">a partial acknowledgment.
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>
该类型计数器统计的进入快速重传阶段的总次数及失败次数,失败次数是指先进入了
recovery阶段,然后有RTO超时了。Fast Recovery没有成功。
首先由于SACK选项已经大面积使用,RenoRecovery的次数应该远小于SackRecovery的次数
另外fail的次数应该比例较小才比较理想
<span class="label">TCPRenoRecovery:
进入Recovery阶段的次数,对端不支持SACK选项
<span class="label">TCPSackRecovery:
进入Recovery阶段的次数,对端支持SACK选项
<span class="label">TCPRenoRecoveryFail: (也放到了RTO次数类别)
先进入Recovery阶段,然后又RTO的次数,对端不支持SACK选项
<span class="label">TCPSackRecoveryFail:(也放到了RTO次数类别)
先进入Recovery阶段,然后又RTO的次数,对端支持SACK选项
</span></span></span></span>
abort本身是一种很严重的问题,因此是否有必要关心这些计数器
后三个计数器如果不为0,则往往意味着系统发生了较为严重的问题,需要格外注意
<span class="label">TCPAbortOnClose:
如果调用tcp_close()关闭socket时,recv buffer中还有数据,则加<span class="number">1
此时会主动发送一个reset包给对端
<span class="label">TCPAbortOnData:
如果在FIN_WAIT_1和FIN_WAIT_2状态下收到后续数据,或TCP_LINGER2设置小于<span class="number">0,则计数器加<span class="number">1
<span class="label">TCPAbortOnTimeout:
因各种计时器(RTO/PTO/keepalive)的重传次数超过上限,而关闭连接时,计数器加<span class="number">1
<span class="label">TCPAbortOnMemory:
如果orphan socket数量或者tcp_memory_allocated超过上限,则加<span class="number">1
一般值为<span class="number">0
<span class="label">TCPAbortOnLinger:
tcp_close()中,因tp->linger2被设置小于<span class="number">0,导致FIN_WAIT_2立即切换到CLOSE状态的次数
一般值为<span class="number">0
<span class="label">TCPAbortFailed:
如果在准备发送reset时,分配SKB或者发送SKB失败,则加<span class="number">1
一般值为<span class="number">0
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>
<span class="built_in">c. 当rcv_buf不足时可能需要prune ofo queue, 这种情况就会导致<span class="type">PruneCalled计数器增加;
当一般都应该通过collapse节省内存就可以了,并不需要真正的prune掉被<span class="type">SACK的数据。
所以<span class="type">OfoPruned和更严重的<span class="type">RcvPruned都应该计数为<span class="number">0。
</span></span></span></span></span></span>
Original: https://www.cnblogs.com/x_wukong/p/10922190.html
Author: 明明是悟空
Title: netstat -st输出解析(二)
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/553986/
转载文章受原作者版权保护。转载请注明原作者出处!