前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >通过TCP Allocate连接数告警了解prometheus-NodeExporter数据采集及相关知识扩散

通过TCP Allocate连接数告警了解prometheus-NodeExporter数据采集及相关知识扩散

作者头像
yaohong
发布2022-05-10 08:34:40
1.4K0
发布2022-05-10 08:34:40
举报
文章被收录于专栏:姚红专栏姚红专栏

1.问题由来

近日有环境告警如下:TCP Allocate连接数过多

很多资料告诉我们使用:netstat –ant | grep ^tcp | wc –l命令查询,但查询的值与告警中获取的只相差很大,于是下载NodeExporter的源码进行查看进行一探究竟。

 源文件:https://cloud.tencent.com/developer/article/1998180

2.NodeExporter源码初探

通过查看node_exporter-1.1.2代码了解到node_sockstat_TCP_alloc调用的是node_exporter.go代码中parseSockstatProtocol函数。

代码语言:javascript
复制
func parseSockstatProtocol(kvs map[string]int) NetSockstatProtocol {
	var nsp NetSockstatProtocol
	for k, v := range kvs {
		// Capture the range variable to ensure we get unique pointers for
		// each of the optional fields.
		v := v
		switch k {
		case "inuse":
			nsp.InUse = v
		case "orphan":
			nsp.Orphan = &v
		case "tw":
			nsp.TW = &v
		case "alloc":
			nsp.Alloc = &v
		case "mem":
			nsp.Mem = &v
		case "memory":
			nsp.Memory = &v
		}
	}

	return nsp
}

进一步分析调用可知TCP Alloc的值取自于/proc/net/sockstat文件。

代码语言:javascript
复制
// NetSockstat retrieves IPv4 socket statistics.
func (fs FS) NetSockstat() (*NetSockstat, error) {
	return readSockstat(fs.proc.Path("net", "sockstat"))
}

那么第一个疑问解决了,知道了TCP Alloc的取值方法。

那么问题来了,为什么netstat –ant | grep ^tcp | wc –l和/proc/net/sockstat查看的不一样。

源文件:https://cloud.tencent.com/developer/article/1998180

3.ss VS netstat

3.1.socket

socket是用于与网络通信的Linux文件描述符。在Linux中,所有东西都是一个文件。在这种情况下,可以将socket视为写入网络而不是写入磁盘的文件。socket在TCP和UDP中有不同的风格。

3.2.procfs

Procfs(proc filesystem)是Linux公开的一种文件系统,它就像窥探内核内存一样。它存在于/proc中,并在/proc/net/tcp和/proc/net/udp 中暴露TCP和UDP套接字的信息。

3.3.ss VS netstat

通过查找netstat相关资料《netstat》了解到如下信息,人们正在从netstat转向ss,因为netstat(实际上是网络工具)已被弃用。但为什么还要如此多的人在使用netstat,猜测是因为netstat也可能被安装在更多的地方。

代码语言:javascript
复制
On Linux, netstat (part of "net-tools") is superseded by ss (part of iproute2). The replacement for netstat -r is ip route, the replacement for netstat -i is ip -s link, and the replacement for netstat -g is ip maddr, all of which are recommended instead.

ss包含在iproute2包中,是netstat的替代品。它除了显示类似于netstat的信息。并且可以显示比其他工具更多的TCP和状态信息。对于跟踪TCP连接和套接字,它是一种新的、非常有用的和更快的(与netstat相比)工具,同时ss直接查询内核,响应速度比netstat快得多。。

关于netstat的替代如下:

代码语言:javascript
复制
$ netstat -r   replaced by   $ ip route
$ netstat -i   replaced by   $ ip -s lin
$ netstat -g   replaced by   $ ip maddr

而ss命令是怎么获取到相关参数的?通过查看ss源码发现ss实际上是解析/proc/net/sockstat的输出

tcp_total在/proc/net/sockstat的输出中实际上是“alloc”;

tcp4_hash在/proc/net/sockstat的输出中实际上是“inuse”;

tcp_tws在/proc/net/sockstat的输出中实际上是“tw”;

因此,/proc/net/sockstat的输出必须与ss -s的输出一致

代码语言:javascript
复制
#  cat /proc/net/sockstat &&  echo "----" && cat /proc/net/sockstat6 && echo "---" && ss -s
sockets: used 7095
TCP: inuse 2066 orphan 0 tw 193 alloc 3235 mem 290
UDP: inuse 6 mem 3
UDPLITE: inuse 0
RAW: inuse 0
FRAG: inuse 0 memory 0
----
TCP6: inuse 1072
UDP6: inuse 4
UDPLITE6: inuse 0
RAW6: inuse 0
FRAG6: inuse 0 memory 0
---
Total: 7095 (kernel 17923)
TCP:   3428 (estab 3079, closed 290, orphaned 0, synrecv 0, timewait 193/0), ports 0

Transport Total     IP        IPv6
*	     17923       -         -        
RAW	       0         0         0        
UDP	      10        6         4        
TCP	      3138      2066      1072     
INET	  3148      2072      1076     
FRAG	  0         0         0  

让我们手动解析下/proc/net/sockstat和sockstat6的输出:

代码语言:javascript
复制
s.tcp4_hashed = 2066 
s.tcp6_hashed = 1072
s.closed      = 290
s.tcp_tws     = 193

我们可得出如下公式:

代码语言:javascript
复制
alloc=s.tcp_total=s.tcp_total =s.tcp4_hashed + s.tcp6_hashed + s.closed  - s.tcp_tws

减去s.tcp_tws是因为290个closed套接字中193个是tcp_tws状态。

关于/proc/net/sockstat的输出信息如下:

代码语言:javascript
复制
sockets: used:已使用的所有协议套接字总量
TCP: inuse:正在使用(正在侦听)的TCP套接字数量。
TCP: orphan:无主(不属于任何进程)的TCP连接数(无用、待销毁的TCP socket数)
TCP: tw:等待关闭的TCP连接数。
TCP:alloc(allocated):已分配(已建立、已申请到sk_buff)的TCP套接字数量。
TCP:mem:套接字缓冲区使用量(单位不详。用scp实测,速度在4803.9kB/s时:其值=11,netstat –ant 中相应的22端口的Recv-Q=0,Send-Q≈400)

 源文件:https://cloud.tencent.com/developer/article/1998180

4.什么是tcp alloc

在socket统计中,有两种类型的TCP套接字:allocated (已分配)的和inuse(使用状态)。

1,.allocated :所有的TCP socket状态都被计数为alloc。

2,inuse:除TCP_CLOSE之外的所有TCP socket状态都被计算为inuse(使用状态)。

在许多情况下,TCP套接字可以标记为TCP_CLOSE。然而,内核将TCP套接字的初始状态设置为“TCP_CLOSE”。

因此,如果名为Closed的列具有较高的数字,而名为timewait的列具有较低的数字,那么应用程序可能会创建TCP套接字,而不做其他任何事情。在许多情况下,内核可能会将一个TCP套接字标记为TCP_CLOSE。这种情况就是其中一种,也是最常见的情况。

源文件:https://cloud.tencent.com/developer/article/1998180

5.NodeExporter采集内存和CPU的方式

5.1.NodeExporter采集内存使用率

在prometheus中获取内存使用率的公式为:

代码语言:javascript
复制
(1 - (node_memory_MemAvailable_bytes{instance=~"$node"} / (node_memory_MemTotal_bytes{instance=~"$node"})))* 100

通过分析NodeExporter的源码node_exporter-1.1.2/node_exporter_test.go,可知内存读取/proc/meminfo文件:

代码语言:javascript
复制
func (fs FS) Meminfo() (Meminfo, error) {
	b, err := util.ReadFileNoStat(fs.proc.Path("meminfo"))
	if err != nil {
		return Meminfo{}, err
	}

	m, err := parseMemInfo(bytes.NewReader(b))
	if err != nil {
		return Meminfo{}, fmt.Errorf("failed to parse meminfo: %v", err)
	}

	return *m, nil
}

从而可知prometheus中node_memory_MemAvailable_bytes的值是取自/proc/meminfo的MemAvailable参数值,node_memory_MemTotal_bytes是取自/proc/meminfo的MemTotal参数值。

而内存使用率公式为:

代码语言:javascript
复制
(1-MemAvailable/MemTotal)*100

5.2.NodeExporter采集CPU使用率

在prometheus中获取内存使用率的公式为:

代码语言:javascript
复制
100 - (avg by (instance) (irate(node_cpu_seconds_total{instance=~"$node",mode="idle"}[5m])) * 100)

通过分析NodeExporter的源码procfs-0.0.8/procfs-0.0.8/stat.go,可知内存读取/proc/stat文件:

代码语言:javascript
复制
func (fs FS) Stat() (Stat, error) {
	fileName := fs.proc.Path("stat")
	data, err := util.ReadFileNoStat(fileName)
	if err != nil {
		return Stat{}, err
	}

	stat := Stat{}

如果通过shell脚本读取/proc/stat文件内容计算出CPU使用率。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-03-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.问题由来
  • 2.NodeExporter源码初探
  • 3.ss VS netstat
    • 3.1.socket
      • 3.2.procfs
        • 3.3.ss VS netstat
        • 4.什么是tcp alloc
        • 5.NodeExporter采集内存和CPU的方式
          • 5.1.NodeExporter采集内存使用率
            • 5.2.NodeExporter采集CPU使用率
            相关产品与服务
            文件存储
            文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档