Linux

記錄每次連接嘗試的 PID

  • February 26, 2015

netstat使用or查找已建立連接的 PID 很簡單lsof。但是,我有一個程序每 60 秒創建一個到我們的數據庫的連接,並通過最大化失敗的連接嘗試限制來鎖定它。我可以將失敗的連接限制增加到數據庫上非常高的值,或者我可以嘗試追踪建立連接的原因,我選擇了後者。

基於 tcpdump/wireshark,我可以看到正在發生的事情是建立了一個連接,然後連接伺服器在伺服器甚至可以響應之前立即關閉連接。我不知道是為什麼。

第一步是找出打開連接的PID。不幸的是,這似乎說起來容易做起來難。問題是當連接進入 TIME_WAIT 狀態時,它不再與 PID 關聯。由於我的連接壽命不到十分之一秒,有沒有辦法記錄這些資訊?

netstat並且lsof似乎能夠每秒輪詢一次,但這對於我正在處理的連接嘗試來說還不夠快。我可以連接一個掛鉤來將此資訊轉儲到日誌中嗎?還是我唯一的選擇是通過循環和一些編碼來強制它?

我使用 CentOS 6。

考慮使用SystemTap。它是動態修補核心的動態檢測引擎,因此您可以跟踪任何核心事件,例如打開套接字。它由 RedHat 積極開發,因此在 CentOS 中得到支持。

安裝

在 CentOS 6 上安裝 SystemTap:

  1. 啟用 debuginfo 儲存庫:
sed -i 's/^enabled=0/enabled=1/' /etc/yum.repos.d/CentOS-Debuginfo.repo
  1. 安裝 SystemTap:
yum install systemtap
  1. 為核心安裝調試資訊包。可以手動完成,但有一個工具可以自動完成:
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

然而,跟踪斷開事件似乎更加棘手。

引用自:https://unix.stackexchange.com/questions/186932