netdata

netdata 是一个分布式实时性能和健康监控系统。netdata 可以实时监控的操作系统和应用程序(如 Web服务器软件 和 数据库服务器软件),并通过现代化的 Web 界面表现出来。netdata 非常的快速和高效,其可以在 物理或虚拟服务器、容器、IoT设备上持续运行。

curl https://my-netdata.io/kickstart-static64.sh >/tmp/kickstart-static64.sh
sh /tmp/kickstart-static64.sh

安装完成访问:http://IP:19999/即可访问。

参考:
https://www.mf8.biz/netdata
https://github.com/firehol/netdata/wiki/Installation


火焰图

yum install perf -y

# 下载火焰图工具。
git clone https://github.com/brendangregg/FlameGraph.git
cd FlameGraph

# 采样(一段时间(通常 20s 足够)之后 ctrl+c,结束采样)
perf record -e cpu-clock -g -p 1572(业务进程 id)

# 用 perf script 工具对 perf.data 进行解析。
perf script -i perf.data &> perf.unfold。

PS:如果在容器中运行的程序有较多的依赖,则该命令解析出来的符号中可能会有较多的“Unregistered symbol…”错误,
此时需要通过--symfs参数指定容器的rootfs位置来解决该问题。
获取容器rootfs的方法根据 docker 的 storagedriver 的不同而有所不同,
如果是device mapper类型,则可以通过 dockerinspect 找到容器的rootfs所在位置,
如果是overlay类型,则需要通过 dockerexport 命令将该容器的rootfs导出来,
如果是富容器的话,一般都有外置的rootfs,直接使用即可。

# 将 perf.unfold 中的符号进行折叠。
./stackcollapse-perf.pl perf.unfold &> perf.folded

# 最后生成 svg 图。
./flamegraph.pl perf.folded > perf.svg

参考:记一次docker问题定位


nginx相关

状态、连接数、进程数

# nginx的运行进程数
ps -ef | grep nginx | wc -l

# 并发连接数和连接状态
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
# 或
netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"t",state[key]}'

一般返回结果如下:
LAST_ACK 5 (正在等待处理的请求数)
SYN_RECV 30 (一个连接请求已经到达,等待确认)
ESTABLISHED 1597 (正常数据传输状态)
FIN_WAIT1 51 (应用说它已经完成)
FIN_WAIT2 504 (另一边已同意释放 )
TIME_WAIT 1057 (处理完毕,等待超时结束的请求数,主动关闭)

其他参数说明:
CLOSED:无连接是活动的或正在进行
LISTEN:服务器在等待进入呼叫
SYN_RECV:一个连接请求已经到达,等待确认
SYN_SENT:应用已经开始,打开一个连接
ESTABLISHED:正常数据传输状态
FIN_WAIT1:应用说它已经完成
FIN_WAIT2:另一边已同意释放
ITMED_WAIT:等待所有分组死掉
CLOSING:两边同时尝试关闭
TIME_WAIT:另一边已初始化一个释放
LAST_ACK:等待所有分组死掉

常用的三个状态是:ESTABLISHED 表示正在通信,TIME_WAIT 表示主动关闭,CLOSE_WAIT 表示被动关闭。

TCP协议规定,对于已经建立的连接,网络双方要进行四次握手才能成功断开连接,如果缺少了其中某个步骤,将会使连接处于假死状态,连接本身占用的资源不会被释放。网络服务器程序要同时管理大量连接,所以很有必要保证无用连接完全断开,否则大量僵死的连接会浪费许多服务器资源。在众多TCP状态中,最值得注意的状态有两个:CLOSE_WAIT和TIME_WAIT。

TIME_WAIT

TIME_WAIT 是主动关闭链接时形成的,等待2MSL时间,约4分钟。主要是防止最后一个ACK丢失。 由于TIME_WAIT 的时间会非常长,因此server端应尽量减少主动关闭连接

CLOSE_WAIT

CLOSE_WAIT是被动关闭连接是形成的。根据TCP状态机,服务器端收到客户端发送的FIN,则按照TCP实现发送ACK,因此进入CLOSE_WAIT状态。但如果服务器端不执行close(),就不能由CLOSE_WAIT迁移到LAST_ACK,则系统中会存在很多CLOSE_WAIT状态的连接。此时,可能是系统忙于处理读、写操作,而未将已收到FIN的连接,进行close。此时,recv/read已收到FIN的连接socket,会返回0。

为什么需要 TIME_WAIT 状态?

假设最终的ACK丢失,server将重发FIN,client必须维护TCP状态信息以便可以重发最终的ACK,否则会发送RST,结果server认为发生错误。TCP实现必须可靠地终止连接的两个方向(全双工关闭),client必须进入 TIME_WAIT 状态,因为client可能面 临重发最终ACK的情形。

为什么 TIME_WAIT 状态需要保持 2MSL 这么长的时间?

如果 TIME_WAIT 状态保持时间不足够长(比如小于2MSL),第一个连接就正常终止了。第二个拥有相同相关五元组的连接出现,而第一个连接的重复报文到达,干扰了第二个连接。TCP实现必须防止某个连接的重复报文在连接终止后出现,所以让TIME_WAIT状态保持时间足够长(2MSL),连接相应方向上的TCP报文要么完全响应完毕,要么被 丢弃。建立第二个连接的时候,不会混淆。

TIME_WAIT 和CLOSE_WAIT状态socket过多

如果服务器出了异常,百分之八九十都是下面两种情况:
1.服务器保持了大量TIME_WAIT状态
2.服务器保持了大量CLOSE_WAIT状态,简单来说CLOSE_WAIT数目过大是由于被动关闭连接处理不当导致的。

因为linux分配给一个用户的文件句柄是有限的,而TIME_WAIT和CLOSE_WAIT两种状态如果一直被保持,那么意味着对应数目的通道就一直被占着,而且是“占着茅坑不使劲”,一旦达到句柄数上限,新的请求就无法被处理了,接着就是大量Too Many Open Files异常,服务崩溃。

参考:http://www.cnblogs.com/qytang/p/5549881.html


负载均衡状态监控

Nginx 负载均衡监测节点状态:
http://www.cnblogs.com/pzk7788/p/6936667.html
http://shmilyjinian.blog.51cto.com/8279182/1730196
http://renzhenxing.blog.51cto.com/728846/1322065/


MySQL相关

# 查看MySQL进程连接数
netstat -antp | grep 80 | grep ESTABLISHED -c4

文章作者: Leo
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 LeoLan的小站
系统管理 性能监控
喜欢就支持一下吧