雲風的 BLOG: 給 skynet 增加網路統計
這些資料通過系統的 netstat 指令也可以查到,但是由 skynet 提供,可以查到更多細節:最關鍵的內部資訊是一個 socket 被繫結在 skynet 的哪個內部服務上,這是系統的 netstat 無法提供的資訊。
在設計獲取統計資訊 api 的時候,我的第一個想法是向 socket 執行緒傳送一個控制訊號,然後由 socket 執行緒做統計,然後通過 socket 資料結構返回。這樣可以迴避多執行緒問題;這類查詢似乎也不太在乎是同步還是非同步的。
但經過幾個小時的思考和推敲,我否定了這個做法。
這樣做的確可以簡化多執行緒的處理,但是擴充套件 socket 訊息結構卻又可能對過去的程式碼照成潛在的相容性風險。雖然這個風險不大,最壞情況只是造成查詢結果的記憶體洩漏。
另外,由於查詢結果是個複雜資料結構,必須由接收方來釋放記憶體,把結果投遞到制定服務同樣也有記憶體洩漏的風險。
更重要的一點是,非同步查詢的介面使用起來會麻煩一些。
所以,最後我還是設計了一個同步查詢 api 。因為這些統計資料只是用來參考,我們不用特別為一致性考慮。我們得到的資料並不是某個時間點的網路狀態的快照。這些統計資料是從 socket 執行緒之外獲取的,在獲取過程中,可能在變化,但我認為沒有什麼壞影響。得益於 skynet 使用的是固定大小的 socket 資料結構陣列(預設最大支援同時 64K 個 socket ,可以通過編譯配置巨集增加),我們不必特別考慮多執行緒下 socket 資料結構的生命期問題,增加這個統計查詢還是挺容易,用一個 double check 就可以保證查詢到的單個 socket 的統計資料是有效的,不需要額外加鎖。
新特性的使用方法是,登入 skynet 的 debug console 輸入 netstat ,或者可以通過 http 協議向 debug console 索取:wget –q –O - http://127.0.0.1:8000/netstat 。
也可以呼叫 socket.netstat() 獲得詳細的資訊(返回在一個 lua table 中)。