源数据获取(/proc/net)

  • 通过读取/proc/net中的文件来获取链接信息, 现仅实现了tcp链接的获取,既读取 /proc/net/tcp、/proc/net/tcp6文件
  • tcp记录字段简介(tcp6相差无几)
    例子:

    local_address    rem_address   st     tx_queue rx_queue tr tm->when retrnsmt   uid        timeout inode
    EE33A8C0:91EC   7C1BA8C0:0185  01    00000000:00000000 00:00000000 00000000 22108254        0 3724516236   1 0000000000000000  20   4  24  12  -1

    字段解释:

    字段释义
    sl连接的编号
    local_address本地地址和端口号,以十六进制表示
    rem_address远程地址和端口号,以十六进制表示
    st连接状态
    tx_queue发送队列的长度(字节数)
    rx_queue接收队列的长度(字节数)
    tr传输控制块的状态
    tm->when传输控制块上一次变化的时间
    retrnsmt传输控制块需要重新传输的次数
    uid连接所属用户的 UID
    timeout传输控制块超时时间
    inode连接对应的 inode 编号

在inode之后的依次排列的信息如下

  • 套接字引用数
  • 套接字实例地址
  • RTO
  • 计算延时的估值
  • 快速确认数和是否启用的标志位的或运算结果
  • 当前拥塞窗口大小
  • 慢启动阈值

数据解析

  • 指标数据维度中包括 链接状态、端口、监听地址、类型、方向,解析过程中会记录这些维度
  • 端口、监听地址的解析:反解析本地地址、本地端口、远程地址、远程端口成可阅读的样式(IP格式、端口整型格式)

    • 地址-网络字节序解析:采用大端字节序的方式解析
    • 端口-主机字节序解析:采用小端字节序的方式解析
  • 链接状态的解析:从映射表中获取得出

    序号链接状态释义
    00EstablishedTCP_ESTABLISHED(已建立连接)
    01SynSentTCP_SYN_SENT(SYN 已发送)
    02SyncRecvTCP_SYN_RECV(SYN 已接收)
    03FinWait1TCP_FIN_WAIT1(等待远程 TCP 发送 FIN)
    04FinWait2TCP_FIN_WAIT2(等待远程 TCP 发送 ACK)
    05TimeWaitTCP_TIME_WAIT(等待一段时间后关闭连接)
    06CloseTCP_CLOSE(连接已关闭)
    07CloseWaitTCP_CLOSE_WAIT(等待远程 TCP 发送 FIN)
    08LastACLTCP_LAST_ACK(等待远程 TCP 发送 ACK)
    09ListenTCP_LISTEN(正在监听连接)
    0AClosingTCP_CLOSING(等待远程 TCP 发送 FIN-ACK)
  • 方向判定出或入:

    • 过程中会优先筛选本地监听地址以及监听端口
    • 如果本地地址+本地端口是所属于本机的监听端口,就会判定为“被访问”的“入”
    • 如果本地地址+本地端口不属于本机监听端口,就会判定为“向外访问”的“出”
    • 如果监听地址为0.0.0.0时,仅需本地端口为监听端口既判断该链接为“入”

流程简介

  1. 读取/proc/net/tcp,如果开启tcp6会读取 /proc/net/tcp6
  2. 解析文件获取原始数据(类似快照)
  3. 解析原始数据,优先筛选出本地监听地址和监听端口,记录本机监听地址池
  4. 解析其余记录,以IP、端口、方向、链接状态、类型进行统计
  5. 输出结果(prometheus exporter 数据格式或其他的)

EdwardQ
36 声望15 粉丝

低调的运维研发Golang 工程师