Linux
記錄每次連接嘗試的 PID
netstat
使用or查找已建立連接的 PID 很簡單lsof
。但是,我有一個程序每 60 秒創建一個到我們的數據庫的連接,並通過最大化失敗的連接嘗試限制來鎖定它。我可以將失敗的連接限制增加到數據庫上非常高的值,或者我可以嘗試追踪建立連接的原因,我選擇了後者。基於 tcpdump/wireshark,我可以看到正在發生的事情是建立了一個連接,然後連接伺服器在伺服器甚至可以響應之前立即關閉連接。我不知道是為什麼。
第一步是找出打開連接的PID。不幸的是,這似乎說起來容易做起來難。問題是當連接進入 TIME_WAIT 狀態時,它不再與 PID 關聯。由於我的連接壽命不到十分之一秒,有沒有辦法記錄這些資訊?
netstat
並且lsof
似乎能夠每秒輪詢一次,但這對於我正在處理的連接嘗試來說還不夠快。我可以連接一個掛鉤來將此資訊轉儲到日誌中嗎?還是我唯一的選擇是通過循環和一些編碼來強制它?我使用 CentOS 6。
考慮使用SystemTap。它是動態修補核心的動態檢測引擎,因此您可以跟踪任何核心事件,例如打開套接字。它由 RedHat 積極開發,因此在 CentOS 中得到支持。
安裝
在 CentOS 6 上安裝 SystemTap:
- 啟用 debuginfo 儲存庫:
sed -i 's/^enabled=0/enabled=1/' /etc/yum.repos.d/CentOS-Debuginfo.repo
- 安裝 SystemTap:
yum install systemtap
- 為核心安裝調試資訊包。可以手動完成,但有一個工具可以自動完成:
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
然而,跟踪斷開事件似乎更加棘手。