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

2023-05-16

1.问题由来

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

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

 源文件:https://www.cnblogs.com/yaohong/p/16046499.html

2.NodeExporter源码初探

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

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文件。

// 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://www.cnblogs.com/yaohong/p/16046499.html

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也可能被安装在更多的地方。

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的替代如下:

$ 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的输出一致

#  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的输出:

s.tcp4_hashed = 2066 
s.tcp6_hashed = 1072
s.closed      = 290
s.tcp_tws     = 193

我们可得出如下公式:

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的输出信息如下:

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://www.cnblogs.com/yaohong/p/16046499.html

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://www.cnblogs.com/yaohong/p/16046499.html

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

5.1.NodeExporter采集内存使用率

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

(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文件:

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参数值。

而内存使用率公式为:

(1-MemAvailable/MemTotal)*100

5.2.NodeExporter采集CPU使用率

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

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文件:

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使用率可参考:LINUX 根据 /proc/stat 文件计算cpu使用率的shell脚本

 源文件:https://www.cnblogs.com/yaohong/p/16046499.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 如何在.NET中创建HTTP请求侦听器Windows服务

    我想创建充当 HTTP 侦听器并可以处理大约 500 个客户端的 Windows 服务 这种服务有什么特别的考虑吗 我对 HTTPListener 类和 TCPListener 类有点困惑 将哪一个用于 Windows 服务将 接受客户端连
  • 套接字编程最佳实践?

    我正在设计一个文件同步应用程序 如 DropBox 客户端在端口 443 上与服务器保持持久的安全 SSL TCP 套接字 每当在客户端上创建 更改 删除文件时 包含相关数据的数据包就会通过套接字发送到服务器 服务器对其进行处理更新服务器上
  • IPv4 允许的最大 TCP/IP 网络端口号是多少?

    可以使用的最大端口号是多少 端口号是一个无符号 16 位整数 即 65535
  • 如何通过 GPRS 向 GPS 追踪器(TK103、GT02、GT06、TK102 等)发送命令

    这已经被问过这里https stackoverflow com questions 25460743 gps tracker tk103 how to send message through server https stackoverf
  • TCPServer 具有同时全双工通信

    我正在尝试编写一个 C 服务器 客户端 它将同时通过 TCP 相互发送字节数组 我正在努力思考如何实现这一目标 我见过的所有示例都等待消息 然后发送响应 我需要同时进行沟通 我是否需要为服务器和客户端上的传入和传出创建 2 个单独的 TCP
  • 如何监控 TCP 连接的 cwnd 和 ssthresh 值? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我希望在通过套接字连接发送或接收数据包时确定这些值 有没有现有的工具可以做到这一点 The ss http linux die net m
  • 如何识别用户空间和内核空间之间的特定套接字?

    我在用户空间中有一个库 可以拦截套接字层调用 例如socket connect accept 等等 我只处理 TCP 套接字 在内核空间中 我有一个网络内核模块 它处理所有 TCP 连接 我需要能够在驱动程序中识别哪些套接字被用户空间库拦截
  • 连接被对等方重置:套接字写入错误。我的 Java 代码出了什么问题

    我正在尝试从独立的 java 应用程序创建并维护到主机的 TCP 连接 本地端口和服务器端口相同 8999 连接后 我必须向服务器发送一条消息 lt STX gt username fred password abcd lt ETX gt
  • 为什么我无法发送这个IP数据包?

    我正在尝试使用 C 发送 IP 数据包 destAddress IPAddress Parse 192 168 0 198 destPort 80 Create a raw socket to send this packet rawSoc
  • 很难理解带有 async_read 和 async_write 的 Boost ASIO TCP 的一些概念

    我很难理解使用 async read 和 async write 时构建 tcp 客户端的正确方法 这examples http www boost org doc libs 1 38 0 doc html boost asio examp
  • TCP Socket无连接超时

    我打开一个 TCP 套接字并将其连接到网络上其他位置的另一个套接字 然后我就可以成功发送和接收数据 我有一个计时器 每秒向套接字发送一些内容 然后 我通过强行断开连接 在本例中拔出以太网电缆 来粗暴地中断连接 我的套接字仍然报告它每秒都在成
  • syn队列和accept队列的混淆

    在阅读TCP源码时 我发现一个困惑的事情 我知道 TCP 在 3 次握手中有两个队列 第一个队列存储服务器收到的连接SYN并发回ACK SYN 我们称之为同步队列 第二个队列存储3WHS成功并建立连接的连接 我们称之为接受队列 但在阅读代码
  • 禁用对特定主机的警报,同时对所有其他主机发出警报

    我有数百台主机向普罗米修斯服务器报告 我的每个主机有很多出口商 我希望能够列出我不希望收到警报的主机列表 我仍然需要对这些主机进行普罗米修斯监控 我尝试过匹配没有接收器的路线 这不起作用 我究竟做错了什么 或者说 我应该怎么做 我的路线规则
  • Linux环境下串口数据转换为TCP/IP

    我需要从Linux系统的串口获取数据并将其转换为TCP IP发送到服务器 这很难做到吗 我有一些基本的编程经验 但对 Linux 的经验不多 有没有开源应用程序可以做到这一点 在 Linux 中您不需要编写程序来执行此操作 只是pipe h
  • 数据包丢失和数据包重复

    我试图找出数据包丢失和数据包重复问题之间的区别 有谁知道 数据包重复 是什么意思 和TCP检测到丢失时重传数据包一样吗 No In TCP 数据包 的传递是可靠的 我认为在这种情况下术语数据应该更好 因为它是面向流的协议 数据包丢失和重复是
  • 在 Python 中通过 TCP 套接字发送文件

    我已经成功地将文件内容 图像 复制到新文件 然而 当我通过 TCP 套接字尝试同样的事情时 我遇到了问题 服务器循环未退出 客户端循环在到达 EOF 时退出 但服务器无法识别 EOF 这是代码 Server import socket Im
  • 在 Golang Server 中接受持久的 tcp 连接

    我正在尝试使用 Go 并且想创建一个 TCP 服务器 我可以通过 telnet 访问该服务器 发送命令并接收响应 const CONN HOST localhost CONN PORT 3333 CONN TYPE tcp func mai
  • C# Socket.receive连续接收0字节且循环中不阻塞

    我正在尝试用 C 编写一个最简单的多线程 TCP 服务器 它接收来自多个客户端的数据 每次连接新客户端时 都会建立套接字连接 并将套接字作为参数传递给新类函数 之后运行 while 循环并接收数据 直到客户端连接为止 这里的问题是 sock
  • 从 celery 工作人员到普罗米修斯的自定义指标

    我有一些 celery 工作人员在 kubernetes 下的容器中运行 它们不会由 celery 自动缩放 并且每个都在单个进程中运行 即没有多处理 我想从他们那里获取一堆不同的指标到普罗米修斯中 我研究过 celery promethe
  • ZeroMQ可以用来接受传统的套接字请求吗?

    我正在尝试使用 ZeroMQ 重写我们的旧服务器之一 现在我有以下服务器设置 适用于 Zmq 请求 using var context ZmqContext Create using var server context CreateSoc

随机推荐

  • 如何保存token-localStorage存储

    1 原理 原理是通过vue router的beforeEach钩子 xff0c 在每次路由到一个地址的时候先判断该路由是否携带了meta信息 xff0c 且该信息中的requireAuth是否为true xff0c 如果为true表示该路由
  • 在Tomcat服务器部署jar包

    在Tomcat服务器部署jar包 1 输出jar包 在eclipse环境下 xff0c 进入Run Configuration界面 xff0c 在Maven Build下选择demo 将Goals的内容改成package 2 将jar包部署
  • PTA 程序设计天梯赛(1~20题)

    文章目录 1 Hello World 5 分 2 打印沙漏 20 分 3 个位数统计 15 分 4 计算摄氏温度 5 分 5 考试座位号 15 分 6 连续因子 20 分 7 A B 20 分 8 计算指数 5 分 9 计算阶乘和 10 分
  • 关于动态(长度不定)结构体数组的两种处理方法

    讲解这个问题 xff0c 以一个例子入手 xff1a PAT xff08 A xff09 1080 Graduate Admission 方法一 xff1a 定义一个结构体数组 xff0c 为该数组开辟一块大的存储空间 xff0c 然后进行
  • 关于C++中string头文件的用法

    注意 xff1a 这里需要声明一点 xff0c 头文件string和string h是不同的 下面的代码是string的使用例子 xff0c 在string头文件下 xff0c 函数中 xff0c 是可以采取string str 61 34
  • 基于VS2010下利用MFC编写软件控制安捷伦信号源

    程控信号源 最近接触关于写 自动化测试软件 xff0c 里面用到了 xff0c 需要实现频谱仪 信号源的程序控制 所以 xff0c 就把每天遇到的问题 xff0c 和学到的知识 xff0c 进行一个总结思考 信号源程控实现 xff1a 信号
  • Qt中emit的用法:发射信号

    emit是为了调用对应的槽函数 xff0c 用来发射信号
  • OAI:Ubuntu20.04不支持OAI

    遇到一个无法解决的问题 xff0c 将ubuntu从18 04升级到了20 04 xff0c 发现ubuntu20 04不支持OAI啊 xff01
  • OAI:eNB模块和UE模块的示波器显示

  • 力扣网页PC端无法进入(问题得到解决)

    最近发现在不同地方 xff0c 使用不同WiFi时 xff0c 有些地点出现力扣网页PC端无法加载的问题 按照网上方法进行了调试 xff0c 发现帖子推荐改hosts文件 xff0c 将自己电脑https leetcode cn com 的
  • Linux临时动态调整kvm虚拟机内存

    一 运维内容描述 同事反馈在用的虚拟机内存不足 xff0c 需要调整 查看一个虚拟机的内存情况 xff0c 最大是8G内存 xff0c 当前内存显示是4G 虚拟机调整最大内存是需要关闭虚拟机的 xff0c 但现在虚拟机上部了服务 xff0c
  • stringstream的用法

    1 用stringstream来分割指定的字符字符串 xff0c 代码如下 xff1a span class token comment 用stringstream来分割指定的字符字符串 span span class token macr
  • C++字符串输入问题

    经常写核心代码模式 xff0c 对于输入输出很多情况下 xff0c 不怎么会写了 所以 xff0c 做个总结 对于如下输入 xff1a span class token comment 输入 xff1a span span class to
  • 中国系统面试0819

    一面 xff1a 30min C 43 43 xff1a 1 C 43 43 的三大特性 xff0c 以及在项目中是如何是用到的 xff08 封装 继承 多态 xff09 2 STL了解哪些 xff0c 在项目中如何使用的 xff0c 举例
  • C语言实现多态

    利用C语言实现多态 xff1a c语言多态的实现 xff0c 需要用到函数指针 函数名实际上是该函数代码存储空间的首地址 xff0c 这个地址可以通过函数指针来存放 通过改变函数指针存储的地址就可以实现多态 span class token
  • 深入浅析Mysql联合索引原理 之 最左匹配原则。

    前言 之前在网上看到过很多关于mysql联合索引最左前缀匹配的文章 xff0c 自以为就了解了其原理 xff0c 最近面试时和大牛交流中 xff0c 发现遗漏了些东西 xff0c 这里自己整理一下这方面的内容 最左前缀匹配原则 在mysql
  • kubernetes Value:将磁盘挂载到容器,PV,PVC

    6 1 介绍卷 6 1 1 卷的类型 emptyDir 用于存储临时数据的简单空目录 hostPath 用于将目录从工作节点的文件系统挂载到pod nfs 挂载到pod中的NFS共享卷 还有其他的如gitRepo gcepersistenD
  • 记一次容器内执行ansible命令卡住

    1 由来 最近在使用kylin v10系统 xff0c 发现当在此系统下运行的容器内执行 ansible localhost m setup 命令会卡住不动 xff0c 于是和同事一起经过如下排查最终找到解决问题的办法 2 环境 2 1 系
  • k8s pod报错Process failed to launch spawn E2BIG

    一 问题描述 近期遇到k8s环境中一个pod无法正常启动 xff0c 启动报错 xff0c PM2 ERROR Process failed to launch spawn E2BIG 二 问题分析 2 1 了解报错相关知识 查阅资料发现
  • 通过TCP Allocate连接数告警了解prometheus-NodeExporter数据采集及相关知识扩散

    1 问题由来 近日有环境告警如下 xff1a TCP Allocate连接数过多 很多资料告诉我们使用 netstat ant grep tcp wc l命令查询 xff0c 但查询的值与告警中获取的只相差很大 xff0c 于是下载Node