netstat
使用或查找已建立连接的 PID 很简单lsof
。但是,我有一个进程每 60 秒创建一个到数据库的连接,并通过最大失败连接尝试限制来锁定它。我可以将数据库上的失败连接限制增加到极高,或者我可以尝试追踪是什么建立了连接,我选择了后者。
基于 tcpdump/wireshark,我可以看到发生的情况是建立了连接,然后连接服务器在服务器响应之前立即关闭连接。我不知道的是为什么。
第一步是找出打开连接的 PID。不幸的是,这似乎说起来容易做起来难。问题是当连接进入 TIME_WAIT 状态时,它不再与 PID 关联。由于我的连接寿命不到十分之一秒,有什么方法可以记录这些信息吗?
netstat
并且lsof
似乎能够每秒轮询,但这对于我正在处理的连接尝试来说根本不够快。是否有一个钩子可以连接到将此信息转储到日志中?或者是我通过循环和一些编码来暴力破解它的唯一选择?
我用的是CentOS 6。
答案1
考虑使用系统点击。它是动态检测引擎,可以动态修补内核,因此您可以跟踪任何内核内事件,例如打开套接字。它是由 RedHat 积极开发的,因此在 CentOS 中得到支持。
安装中
要在 CentOS 6 上安装 SystemTap:
启用调试信息存储库:
sed -i 's/^enabled=0/enabled=1/' /etc/yum.repos.d/CentOS-Debuginfo.repo
安装系统Tap:
yum install systemtap
安装内核的 debuginfo 包。它可以手动完成,但有一个工具可以自动完成:
stap-prep
追踪
SystemTap 没有 TCP 连接的 Tapset 探针,但您可以直接绑定到内核函数!您也可以在套接字级别执行此操作。
即创建名为conn.stp
:
probe kernel.function("tcp_v4_connect") {
printf("connect [%s:%d] -> %s:%d\n", execname(), pid(),
ip_ntop(@cast($uaddr, "struct sockaddr_in")->sin_addr->s_addr),
ntohs(@cast($uaddr, "struct sockaddr_in")->sin_port));
}
这将为您提供以下输出:
# stap conn.stp
connect [nc:2552] -> 192.168.24.18:50000
connect [nc:2554] -> 192.168.24.18:50000
connect [nc:2556] -> 192.168.24.18:50000
然而,跟踪断开连接事件似乎更加棘手。