查看一个socket的开始时间

问题起源

有一个服务分布在3个数据中心, 有一个统一的FQDN(svc1.vip.tianxioahui.com)让别人去访问它, 同时每个数据中心都有一个单独的IP来访问该服务, 也就是说这个域名能解析到3个不同的IP. 有一次某个数据中心的该服务出现了点问题, 于是对应的IP被从DNS服务器上临时去掉了. 当问题修复之后, DNS服务器上恢复对应的IP, 该数据中心的流量却没有恢复, 还是流向了其它2个数据中心. 问题到底出现在哪呢?

初步调查

该服务的使用方是我们内部的一个服务, 于是我们首先检查客户端的DNS解析. 同时, 我们的DNS服务器会根据查询者所在的数据中心首先返回本数据中心的IP, 当没有对应数据中心的IP之后, 才会返回不同的数据中心的IP.

正常情况下的服务访问情况:
Screen Shot 2023-02-10 at 20.47.20.png

当 DC-C 的服务出问题的时候:
Screen Shot 2023-02-10 at 20.49.26.png

于是我们登录之前出问题数据中心某个客户端, 查询 DNS 解析情况, 发现查询的结果就是已经恢复的数据中心的IP, 也就是DNS解析已经完全恢复.

于是通过 ss 去查看现存的tcp连接, 发现确实是连接到其它数据中心的.

为什么恢复后还连接到其它数据中心?

首先经过连续多次测试, DNS解析的结果仍然是当前数据中心的IP, 所以DNS解析完全是正常的. 所以怀疑这个连接是之前早就建立好的, 并且一直 keep-alive, 所以一直还是正常在用的.

如何确定这个连接已经存活多久了?

我们想通过最简单的方式: ss 命令, 看看它是否提供了一个tcp连接的开始时间man ss答案是, 并没有.

于是, 我们找到这篇: https://superuser.com/questions/565991/how-to-determine-the-socket-connection-up-time-on-linux

这个问题的最高评答案里面给的过程是:

  1. 找到这个tcp连接所在的进程和proc文件系统的inode
  2. 然后使用stat命令去查看文件的最后访问时间(回答里用的是: query the file access time of the symbolic link)

然而这个并不是socket uptime, 而是socket最后的访问时间, 可是那个shell函数又命名为suptime, 真是对不上.

但是, 他使用stat访问文件的创建时间是对的

文件创建时间

通常情况下,使用stat都能查看文件的创建时间, 比如:

supra@suprabox:~$ stat ./bootstrap.sh
  File: ./bootstrap.sh
  Size: 4162          Blocks: 16         IO Block: 4096   regular file
Device: fd01h/64769d    Inode: 10763859    Links: 1
Access: (0775/-rwxrwxr-x)  Uid: ( 1000/   supra)   Gid: ( 1000/   supra)
Access: 2022-11-22 19:06:03.507882931 -0800
Modify: 2022-11-22 19:05:59.487695031 -0800
Change: 2022-11-22 19:05:59.491695212 -0800
 Birth: 2022-11-22 19:05:59.487695031 -0800

上面最后一行 Birth 就是它的创建时间.

查看socket inode的创建时间

其实上面输出中的 Birth 是在 inode 的元数据里的, 所以, 如果我们按照那个答案的方法去访问socket虚拟文件的inode是不是就找到了socket 的创建时间?

sudo ss -t -p -e
State    Recv-Q  Send-Q   Local Address:Port     Peer Address:Port      Process
ESTAB    0       0        10.249.64.103:ssh      10.226.199.52:61340    users:(("sshd",pid=812231,fd=4),("sshd",pid=812101,fd=4)) timer:(keepalive,54min,0) ino:2211652 sk:5063 cgroup:/system.slice/ssh.service <->

ss命令通过制定 -p 参数, 现实进程号和fd信息(pid=812101,fd=4), 通过-e参数, 显示inode 信息(ino:2211652). 于是, 我们可以查看这个虚拟文件的inode 信息了

supra@suprabox:~$ sudo stat /proc/812101/fd/4
  File: /proc/812101/fd/4 -> socket:[2211652]
  Size: 64            Blocks: 0          IO Block: 1024   symbolic link
Device: 17h/23d    Inode: 2228948     Links: 1
Access: (0700/lrwx------)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2023-02-11 01:51:35.510079439 -0800
Modify: 2023-02-11 01:51:26.442196746 -0800
Change: 2023-02-11 01:51:26.442196746 -0800
 Birth: -

可是Birth 这行是空.
文件的符号链接指向 socket:[2211652], 这个方括号里面的值就是我们通过ss查看得到的 inode id.

同时, 我们去查看 cat /proc/net/tcp 也能看到一样的行

最终, 也没找到一个可以查看socket创建时间的命令.

标签: none

添加新评论