← 所有文章

FIELD NOTES / 工業通訊與網路

封包時間戳如何量測往返時間而不混用設備時鐘

工業通訊與網路作者:站長預估 5 分鐘閱讀

以同一本機單調時鐘拆解送出、首資料、完整回覆與解析時間,避免跨設備時鐘及重試配對造成錯誤RTT。

本文目錄

先決定你要量測哪一段時間

看到通訊慢,先把量測名稱寫完整。應用往返時間從本機送出請求的指定事件,到本機收到並辨認完整回覆;TCP封包往返則通常對照資料與其確認。兩者包含的處理不同,不能把設備回應內的時間直接減本機送出時間就叫RTT。

本文示範同一程序、同一單調時鐘內的時間差。準備請求識別、連線世代、開始送出、送出完成、首位元組到達、末位元組到達及解析完成六類紀錄。先定義事件位置,再寫單位;毫秒、微秒或奈秒要在欄名與報告中一致。

單調時鐘適合量測經過時間,不受一般牆上時鐘向前或向後校正影響;但其原點沒有跨設備意義。主機A的單調值一千秒與主機B的一千秒不能直接相減,重啟前後也須核對時鐘域和啟動識別。

適用於有請求回覆關聯的上位機或通訊服務。本篇不提供特定PLC計時指令,也不聲稱所有平台的單調時鐘都包含待機時間。實際計時API、解析度、暫停行為與執行緒排程誤差,應依目標作業系統文件確認。

跟著算一次應用往返時間

假設本機記錄送出開始100.000秒、送出完成100.004秒、首位元組100.030秒、末位元組100.035秒、解析完成100.037秒。以送出開始到解析完成定義應用往返,結果為37毫秒;以送出完成到首位元組定義等待,則是26毫秒。

分段核算為送出呼叫4毫秒、送出完成後等待首資料26毫秒、首到末資料5毫秒、末資料到解析完成2毫秒,合計37毫秒。這些名稱描述程式觀測點,不直接代表純網路或純設備耗時;例如接收執行緒未即時排程也會增加觀測等待。

送出完成只表示API在其契約下接受資料,不代表設備收到,更不代表已完成控制動作。TCP確認也不是業務完成訊號。報告應將傳輸進度、協定回覆與業務完成分欄,不要把37毫秒標成設備機械動作完成時間。

若設備另外回報自身接收2000.010秒、完成2000.018秒,在同一設備時鐘域內可算8毫秒處理時間。不能計算2000.010減100.000當去程延遲;兩者原點不同。即使都顯示UTC,也需要同步誤差與事件位置證據才能估單程。

練習把解析完成改為100.047秒,其他不變。應用往返變47毫秒,末資料至解析完成變12毫秒;首資料等待仍26毫秒。這指向接收後處理的觀測延遲增加,尚不能只憑數字指定某個函式或CPU是根因。

把重傳與重試放回正確請求

每筆量測以connection_epoch加request_id配對。一次應用重試另加attempt編號,業務操作識別可依冪等策略維持相同。TCP內部重傳不等於新的應用attempt;分開記錄才能知道是傳輸修復,還是應用逾時後又送一次。

案例原請求在0毫秒送出,200毫秒達期限,第二次嘗試250毫秒開始,300毫秒收到明確屬第二次的完整回覆。第二次嘗試耗時50毫秒,從原請求開始到結果是300毫秒;不可只報50而藏掉第一次等待及退避。

如果300毫秒的回覆無法區分第一次或第二次,就不能硬配給第二次。應標關聯不明,保留原始內容並依協定隔離晚到回覆。這在沒有交易識別的串列協定尤其重要,量測程式不能靠「最近一次送出」保證正確配對。

只有收到首位元組不能結束完整回覆計時。若長度宣告十個bytes卻只收到四個,後續逾時應記部分回覆及已收長度,不能以首包時間當成功。例外回覆也是完整協定回覆,但業務結果應另列失敗或拒絕。

重複回覆不能產生兩筆成功樣本。完成後保留有限的識別紀錄,將重複資料標示Duplicate;超過保留窗口而無法辨認時,標Unknown。統計成功耗時與錯誤數時,每個操作與attempt的計數規則都要固定。

用封包擷取補足觀測誤差

若使用封包擷取,先保存擷取介面、時間戳來源、軟體或硬體時間戳、解析度與擷取位置。同一工具顯示許多小數位,只表示格式或解析度,不代表實際準確到那個位數。主機排程、擷取丟包與卸載功能都可能影響解讀。

同一擷取點上,請求最後資料到完整回覆最後資料的時間差,與程式記錄的送出開始至解析完成不同。先說明TCP序列範圍與完整訊息邊界,再報數字;不要把不同定義的兩份報告直接比較,得出改版快十毫秒的結論。

若要以資料及ACK估TCP RTT,須處理重傳歧義,不能把重傳後收到的ACK直接當第一份資料的精確往返。RFC6298說明TCP計時與重傳相關原則;應用教學可保留工具結果,但要註明它是TCP層觀察而非設備處理時間。

跨主機的兩份擷取檔,只有在時鐘同步、誤差界限與事件位置皆可信時,才可進一步估算單程延遲。來回路徑可能不對稱,因此把RTT除二只能作對稱假設下的估算,不是實際去程或回程量測。

失敗時先查是否配錯請求、混用時鐘、單位錯誤或只量到首資料,再查排程與封包證據。若量測出負耗時,不要取絕對值掩蓋;保存兩端原始時間與時鐘域,修正量測邊界後重新取樣。

完成結果與常見問題

完成後應交出每筆原始時間、各段差值、請求與嘗試識別、成功或逾時結果,以及統計範圍。平均值之外保留樣本數與長尾資料;逾時不能被當成零秒,也不能全部刪掉後宣稱連線穩定。

例如十次查詢有九次成功、一個逾時,你可以報九筆成功樣本的平均延遲,但要同時報成功9/10及一筆逾時。若另有總期限,超過期限後收到的回覆仍列晚到,不因有數值就改寫原本期限結果。

問:設備回的UTC可以減本機送出UTC嗎?答:只有在時鐘關係、誤差與事件語意已確認時才能估跨端時間差;一般RTT優先用同一本機單調時鐘。

問:RTT除二就是單程嗎?答:只是在路徑和處理對稱假設下的估算,真實單程可能不同。

問:收第一個byte能算完成嗎?答:那是首資料等待,完整回覆與解析完成另記,不能混為一個指標。

問:只報重試成功那次的時間可以嗎?答:可作單次attempt指標,但還要保存原始操作的總耗時、退避與失敗次數,才能判斷使用者實際等待。

本例時間均為案例條件,已核算差值。上線前先用可控延遲的測試回覆核對事件位置,再在目標負載下驗證。

參考:Python time.monotonic官方文件:單調時鐘與差值用途,非PLCAPI。

參考:RFC6298:TCP重傳計時與RTT取樣原則,非應用完成時間。

延伸閱讀