# 以統計觀點看電腦網路傳輸品質
> 資料整理:[jserv](https://wiki.csie.ncku.edu.tw/User/jserv)
本文討論如何以統計方法觀察電腦網路傳輸品質。主體想法是將延遲、吞吐量、jitter、封包遺失等原始指標,轉換成可比較、可組合的正規化特徵,再用單一圖像或指數呈現「是否異常」與「異常可能來自何處」。這種做法的目標不是取代所有傳統量測,而是降低多指標同時判讀的成本,協助更早辨識壅塞、突發抖動與非壅塞型封包遺失。
> 本文改寫自[傳輸品質評估系統簡介](https://blog.csdn.net/dog250/article/details/143164573)
## 為什麼需要統一的評估方法
網路品質分析通常同時涉及多項量測值,例如 RTT、吞吐量、封包遺失率與 jitter。這些指標的單位、量級、取樣頻率與統計性質都不相同,因此若直接並列觀察,常會遇到三個問題:
- 不同指標難以直接比較
- 同一個現象可能同時影響多個指標,但影響方向不同
- 單一指標偶發波動,未必足以代表真實異常
若要將這些資訊用於預警或自動化決策,就需要一套統一的表示方式。本文將這種表示方式稱為「指數圖像」:先將各指標轉成方向一致的特徵,再透過組合函數放大同時出現的異常訊號。
## 主體概念
為避免術語混淆,先定義本文使用的幾個概念:
- 顯式特徵:可直接由量測資料取得,且和特定異常現象有明確關聯的特徵,例如 RTT 偏高、吞吐量偏低、jitter 偏高
- 陽性特徵:將顯式特徵經過正規化與方向統一後得到的值,數值越大,代表該特徵越支持某種異常判斷
- 指數圖像:將多個陽性特徵在時間軸上組合後形成的曲線,用來觀察異常是否在某段時間集中出現
這裡的「陽性」不是醫學意義上的好或壞,而是「對某個假設提供支持」。例如,若目標是判定壅塞,那麼 RTT 偏高與 jitter 偏高可以視為壅塞假設的陽性特徵;若目標是判定傳輸順暢,那麼高吞吐量才會是陽性特徵。重點不在特徵本身的語意,而在於特徵方向必須先被統一。
本文有時也用「激勵」(activation,或稱啟動) 來描述同一個轉換過程。在類神經網路中,sigmoid 作為激勵函數,決定神經元是否被啟動;在本文的框架中,sigmoid 或 CDF 作為對映函數,決定某個指標是否「被啟動」為陽性。兩者的數學結構相同,只是應用場景不同,因此「激勵」和「陽性判定」在本文中可視為同一件事的不同描述。
## 建構指數圖像的流程
可將流程拆成五個步驟:
1. 選定觀測目標,例如持續性壅塞、突發性抖動或非壅塞型封包遺失
2. 為每個目標挑選顯式特徵,例如壅塞可能對應 RTT 均值上升與 RTT 變異增加
3. 將原始量測轉成方向一致的陽性特徵,對映至固定區間,例如 $[0, 1]$
4. 用組合函數整合多個陽性特徵,使多項特徵同時出現時輸出明顯上升
5. 以滑動時間窗繪製曲線,並搭配實際吞吐量或 RTT 變化做對照
如果某個指標本身是「越大越糟」,例如 RTT 或 jitter,可以直接使用遞增對映;若某個指標是「越小越糟」,例如吞吐量,則必須先反向處理,例如使用 $1 - F(x)$、對量測值取負,或改以「吞吐量下降幅度」作為輸入,否則將和其他特徵方向衝突。
## 用 sigmoid 做第一版正規化
最直觀的做法,是將原始量測丟進一個單調函數,使輸出落在固定區間。這種函數不一定要是標準 logistic sigmoid,但必須滿足二個條件:
- 輸出可正規化到固定範圍
- 能夠在臨界區附近放大差異
文獻常用如下形式:
$$
f(x) = \frac{a}{1 + e^{bx}} + c
$$
其中 $a > 0$、$b < 0$,可使函數隨輸入遞增。sigmoid 函數 (也稱為邏輯函數) 常以 $\sigma(x)$ 或 $\text{sig}(x)$ 表示,其圖像為平滑的 S 形曲線,導數呈鐘形分佈:

這類函數的優點是形狀平滑,且容易表達「超過某個門檻後快速上升」的特性,因此很適合拿來描述陽性特徵。
本文所用的 sigmoid 做了一項關鍵修改:刻意讓輸出在正向區間的最大值略微超過 1。這個設計是為了配合後續的乘積型組合函數;當每個陽性特徵的對映值 $a_i$ 都略大於 1 時,乘積 $(\prod a_i)^n$ 會隨冪次放大,反之,只要任一 $a_i$ 小於 1,乘積就會被壓低。這構成一種 soft-AND 效果:雖非嚴格的邏輯 AND (例如 $1.05 \times 0.99$ 仍略大於 1),但多數特徵偏低時,乘積會被顯著壓低,實務上足以區分「全面異常」與「零星波動」。

不過,sigmoid 也有明顯限制。它的斜率、平移量與輸出範圍都需要事先校準,而不同網路路徑、不同時間帶、不同服務型態,往往有不同的基準值。若每個場景都要手動調參,實務維護成本會很高。
## 從固定函數走向資料驅動對映
在實際系統中,比起直接手調 sigmoid,更穩健的做法通常是使用歷史資料建立經驗分佈,再把該分佈的累積結果當成對映函數。也就是說,對某個指標蒐集足夠多的觀測值後,可建立經驗分佈,再用經驗累積分佈函數 (empirical CDF, ECDF) 近似「正常情況下,這個值有多極端」。
這種方法的優點有三個:
- 可直接反映真實環境中的量測分佈
- 不必為每個路徑手動指定 sigmoid 參數
- 能自然處理偏態、重尾或多峰分佈
但這不代表 ECDF 一定比人工設計的 sigmoid 更準確。它的效果仍取決於資料量、觀測期間是否穩定、是否存在日夜週期或路由變動,以及樣本是否能代表未來流量。因此,較合理的說法是:ECDF 可減少人工調參,並讓對映函數更貼近歷史分佈,但前提是資料品質足夠好,且基準分佈必須持續更新。
從數學角度看,CDF 與 sigmoid 的相似性並非巧合。任何連續隨機變數的 CDF 都是單調遞增、值域在 $[0, 1]$ 的曲線,這正是 sigmoid 的核心特性 (ECDF 本身是階梯函數,實務上可視需要做平滑或分位數近似)。差別在於:sigmoid 的形狀由人工參數決定,而 CDF 的形狀由資料本身決定。因此,用 ECDF 取代人工設計的 sigmoid,本質上是從「手動選參」轉向「依歷史分佈決定分位位置」。這不代表一定要先估計機率密度函數 (PDF);在許多實作中,只靠樣本排序與累積比例,就足以完成對映。這也意味著,「激勵」與「陽性」的判斷,其實是在檢查某件事的累積出現是否已達到某種臨界量,亦即從量變邁向質變,而 ECDF 天然描述的正是這種累積轉換。
不過,ECDF 的輸出值域嚴格限制在 $[0, 1]$,而前述乘積型組合函數要求陽性特徵的對映值在某個門檻之上時能略微超過 1,才能發揮 soft-AND 效果。因此,在實務上採用 ECDF 時,通常會加上一個縮放因子,例如:
$$
a_i = \alpha \cdot \text{ECDF}(x_i), \quad \alpha > 1
$$
其中 $\alpha$ 略大於 1 (如 1.05 或 1.1)。此時,$a_i > 1$ 的條件其實是 $\text{ECDF}(x_i) > 1 / \alpha$。也就是說,若 $\alpha = 1.1$,則大於約 P90.9 的觀測值就會超過 1,不必等到最極端尾端才成立。因此,$\alpha$ 不能只憑直覺指定,而必須和欲標示為「陽性」的分位門檻一起設計。若確實只希望高尾端才超過 1,可改寫為:
$$
a_i = 1 + \beta \cdot (\text{ECDF}(x_i) - \tau), \quad 0 < \tau < 1
$$
其中 $\tau$ 明確表示陽性啟動門檻,$\beta$ 控制放大量。當 $\text{ECDF}(x_i) > \tau$ 時,$a_i > 1$,對應陽性;當 $\text{ECDF}(x_i) < \tau$ 時,$a_i < 1$,在乘積中會壓低整體輸出,維持 soft-AND 的抑制特性。需注意 $\beta$ 與 $\tau$ 的搭配必須確保 $a_i$ 始終為正 (例如 $\beta < 1/\tau$)。無論採用哪一種形式,若 $\alpha$ 或 $\beta$ 太大,雜訊都會被一起放大。
## 如何決定對映方向
將 CDF 或 ECDF 當作對映函數時,方向必須和判斷目標一致:
- 對 RTT、jitter、封包遺失率這類「越大越糟」的指標,可直接使用 $F(x)$,值越大代表越偏向異常尾端
- 對吞吐量這類「越小越糟」的指標,不能直接把高分位數當成異常,應改看低尾端;若輸入是原始吞吐量,可使用反向對映或低分位數界定異常,若輸入改成「吞吐量下降量」,則可直接把它視為「越大越糟」的量,再使用 $F(x)$
這點很重要。若不先統一方向,就會出現「高吞吐量也被對映成高陽性」的矛盾,導致不同特徵在組合時互相抵銷,甚至得出錯誤判斷。
可用下表快速整理常見指標的方向:
| 指標 | 原始意義 | 建議輸入量 | 建議對映方向 |
|------|----------|------------|--------------|
| RTT | 越大越糟 | 原始 RTT | 直接使用 $F(x)$ |
| jitter | 越大越糟 | 原始 jitter | 直接使用 $F(x)$ |
| 封包遺失率 | 越大越糟 | 原始遺失率 | 直接使用 $F(x)$ |
| 吞吐量 | 越小越糟 | 原始吞吐量 | 反向對映,或以低分位數定義異常 |
| 吞吐量下降量 | 越大越糟 | 基準吞吐量減去當前吞吐量 | 直接使用 $F(x)$ |
## 最小可算例子
以下用一個極簡例子,示範如何把原始量測轉成陽性特徵,再組合成單一指數。假設我們想判斷某條路徑是否出現壅塞,並選用 3 個指標:
- RTT,越大越糟
- jitter,越大越糟
- 吞吐量下降量,越大越糟
再假設這條路徑的歷史 ECDF 已整理如下:
| 指標 | 目前觀測值 | ECDF 值 |
|------|------------|---------|
| RTT | 82 ms | 0.97 |
| jitter | 14 ms | 0.93 |
| 吞吐量下降量 | 18 Mbps | 0.96 |
若採用帶門檻的對映
$$
a_i = 1 + \beta \cdot (\text{ECDF}(x_i) - \tau)
$$
並設定 $\tau = 0.9$、$\beta = 0.5$,則 3 個陽性特徵分別為:
$$
\begin{aligned}
a_{\text{RTT}} &= 1 + 0.5 \cdot (0.97 - 0.9) = 1.035 \\
a_{\text{jitter}} &= 1 + 0.5 \cdot (0.93 - 0.9) = 1.015 \\
a_{\text{drop}} &= 1 + 0.5 \cdot (0.96 - 0.9) = 1.030
\end{aligned}
$$
若組合函數採乘積形式,且取 $n = 2$,則壅塞指數為:
$$
I = \left( 1.035 \times 1.015 \times 1.030 \right)^2 \approx 1.166
$$
由於 3 個特徵都略高於 1,乘積在平方後被進一步放大,因此可解讀為「多個支持壅塞的訊號同時出現」。反過來說,若其中一個特徵沒有超過門檻,例如 jitter 的 ECDF 只有 0.6,則
$$
a_{\text{jitter}} = 1 + 0.5 \cdot (0.6 - 0.9) = 0.85
$$
此時
$$
I = \left( 1.035 \times 0.85 \times 1.030 \right)^2 \approx 0.819
$$
即使 RTT 與吞吐量下降量都偏高,整體指數仍會被壓低。這正是乘積形式想保留的 soft-AND 特性。
## 組合函數的設計
當多個陽性特徵都已對映到固定區間後,就可以將它們組合成單一指數。常見做法有兩類。
第一類是偏向 AND 特性的乘積形式:
$$
I = \left( \prod_i a_i \right)^n
$$
只要其中某個 $a_i$ 很小,整體輸出就會明顯下降,因此適合拿來描述「必須多個條件同時成立」的異常,例如持續性壅塞。
第二類是偏向累加效果的求和形式:
$$
I = \left( \sum_i a_i \right)^n - \sum_i a_i
$$
這種做法對總活化量 (total activation) 敏感,較不像乘積形式那樣嚴格抑制個別弱值,因此行為偏向累加型聚合。適合用在「只要整體異常程度夠高就值得注意」的場景,但無法區分「單一指標極端」與「多個指標同時中度偏高」。
不過,這類函數要成立,仍需先交代前提。如前述,本文使用的 sigmoid 輸出上限略微超過 1,因此各 $a_i$ 的實際值域約為 $[0, 1.05]$ (視參數而定)。以 1 為分界,陽性特徵對應 $a_i > 1$,非陽性對應 $a_i < 1$,乘積形式在這個設計下才能發揮 soft-AND 效果。至於求和形式,若直接使用 $\left( \sum_i a_i \right)^n - \sum_i a_i$,則必須至少滿足二個條件:一是 $n > 1$,二是要注意其輸出尺度會隨特徵數量增加而改變,當 $\sum_i a_i < 1$ 時甚至可能出現負值。因此,若希望不同時間段或不同指數之間可比較,實務上通常還需要先將 $\sum_i a_i$ 除以特徵數量,或在輸出後再次正規化,否則它更適合作為輔助排序分數,而不是可直接比較的絕對指數。
實務上,真正重要的不是公式是否華麗,而是它能否符合判斷邏輯。若目標是辨識壅塞,就應讓 RTT 升高、jitter 升高、吞吐量下降同時出現時,指數才明顯抬升;若只是單一樣本的偶發雜訊,則應被時間窗或組合函數抑制。
## 以模擬場景說明分類方式
假設我們觀察四種情況:
| 狀況 | RTT | RTT 變異 | 吞吐量 | 吞吐量變異 |
|------|-----|----------|--------|------------|
| 持續性壅塞 | 高 | 中至高 | 低 | 中 |
| 突發性壅塞 | 高 | 高 | 低 | 高 |
| 高封包遺失率 (非壅塞) | 中 | 中 | 低 | 高 |
| 低封包遺失率 (非壅塞) | 近正常 | 近正常 | 輕微下降 | 低至中 |
從這個表可以看出,不同異常未必由單一指標決定。例如,高封包遺失率可能造成吞吐量明顯下降,但 RTT 未必顯著上升;而突發性壅塞通常會同時拉高 RTT 與其變異。也就是說,若只看單一指標,很難做出穩健判斷,但若將多個方向一致的特徵組合,就能提高可辨識性。
原始模擬可用類似下列的 Python 程式碼構造不同區段。其中 `wx[n]`、`wy[n]` 分別代表兩條資料流在時間步 `n` 的壅塞視窗大小,`C` 為鏈路頻寬,`R` 為基準 RTT,`Buff` 模擬佇列中累積的緩衝量,`drate` 為封包遺失機率。最後的 `while` 迴圈確保兩條流加上緩衝不超過 BDP ($C \times R$) 加上約 0.2 BDP 的佇列餘裕:
```python
if n > 500 and n <= 1000:
# 隨機突發壅塞
Buff = random.randint(0, 20)
elif n > 1500 and n <= 2000:
# 持續壅塞
Buff = 20
elif n > 2500 and n <= 3000:
# 逐漸壅塞
Buff += 0.04
elif n > 3500 and n <= 4000:
# 高封包遺失率,非壅塞
Buff = 0
if random.random() < drate:
wx[n] = wx[n] / 2
wy[n] = wy[n] / 2
elif n > 4200 and n <= 4600:
# 低封包遺失率,非壅塞,僅影響單一資料流
Buff = 0
if random.random() < drate / 50:
wx[n] = wx[n] / 2
else:
Buff = 0
while wx[n] + wy[n] + Buff > 1.2 * C * R:
wx[n] = wx[n] / 2
wy[n] = wy[n] / 2
```
接著將各種異常各自對應的陽性特徵畫成時間序列,並與實際吞吐量曲線並排顯示,就能得到一組可對照的「指數圖像」。

圖像的判讀方式可以整理成三個步驟:
1. 先找出吞吐量或 RTT 出現異常波動的時間區段
2. 對照各個指數圖像,觀察哪些異常假設在同一時間抬升
3. 以抬升最穩定、最符合特徵組合邏輯的那組指數,作為主要診斷線索
以下為將多個指數圖像與實際頻寬變化一同對照顯示的範例:

這種方法的價值,在於它不是直接把任何波動都視為問題,而是要求「多個支持同一假設的特徵」在時間上同時出現。若某段時間只有零星尖峰,卻沒有形成持續的組合訊號,就不應輕易驅動協定進入保守模式。
## 為什麼時間窗與平滑不可省略
若只看單點量測,幾乎任何網路都會出現短暫雜訊,因此指數圖像必須搭配時間窗與平滑機制,例如移動平均、指數加權移動平均或中位數濾波。其目的有二個:
- 抑制偶發樣本造成的誤報
- 放大具有持續性的結構變化
不同平滑器的反應速度不同。低通特性較強的濾波器,可以更清楚地呈現持續性異常,但也會拉長反應時間;反之,反應較快的濾波器能早期偵測變化,卻較容易把毛刺當成真實事件。因此,平滑器本身就是評估系統的一部分,而不是單純的視覺化修飾。
實務上,網路異常可細分為「瞬時突發」與「趨勢漂移」兩種時間尺度。若只用單一時間窗,短窗對突發敏感但容易誤報,長窗對趨勢穩定但反應遲鈍。一種常見做法是同時維護短窗 (如 1 秒) 與長窗 (如 30 秒) 兩組指數:當短窗指數抬升但長窗尚未跟上時,可能只是瞬時毛刺;當兩者同時抬升時,則更可能是結構性變化。透過觀察兩組指數的交會時機與持續時間,可在靈敏度與穩定性之間取得更好的折衷。

## 真實資料中的分佈,不一定像教科書
在真實網路中,各指標的分佈往往不像標準常態分佈那樣整齊。
RTT 主要受路徑長度、排隊延遲與中途裝置處理延遲影響。若路徑穩定,RTT 常呈集中但右偏的分佈。教學上常用 $\mu + 3\sigma$ 當成異常界線 (若分佈近似常態,單尾超過 $\mu + 3\sigma$ 的機率約為 0.135%),但這只在分佈近似常態時比較合理;若尾端偏態明顯,則改用經驗分位數,例如 P95 或 P99,通常更穩健。若本文採資料驅動對映作為主軸,那麼分位數或 ECDF 也應視為比固定常態假設更優先的實務做法。
吞吐量則更複雜。它可能受到多個瓶頸鏈路、交叉流量、傳輸控制演算法與路由選擇影響,因此常出現多峰或長尾。此時,與其硬套單峰分佈模型,不如直接以 ECDF 描述歷史觀測,再定義「落入低尾端」的程度作為陽性特徵。
jitter 通常和 tail latency 高度相關。當排隊行為或排程延遲突然放大時,平均 RTT 未必立刻飆升,但 jitter 常先變得明顯。因此,在低延遲服務或互動型應用中,jitter 常是比平均延遲更早出現的警訊。



## 進階統計工具
對於追求更高精準度或需要處理極端事件的場景,ECDF 可搭配更強大的統計方法。
當關注的是 P99.9 甚至更極端的尾端延遲時,ECDF 在該區間的樣本通常嚴重不足,分位數估計會非常不穩定。[極值理論](https://en.wikipedia.org/wiki/Extreme_value_theory) (Extreme Value Theory, EVT) 提供了一套嚴謹的框架來處理這類問題。其中 peaks-over-threshold 方法可從超過某個高門檻的觀測值中,擬合 [Generalized Pareto Distribution](https://en.wikipedia.org/wiki/Generalized_Pareto_distribution) (GPD),進而推估極端分位數的位置。將 GPD 的 CDF 當作高尾區段的對映函數,可以在樣本稀少的情況下,為「黑天鵝等級」的延遲事件提供比純 ECDF 更穩定的陽性對映。
另一個實務挑戰是多觀測點的時間對齊。當多個節點同時出現異常時,由於傳播延遲與取樣時間差,各節點的指數抬升時間點可能略有位移。[動態時間規整](https://en.wikipedia.org/wiki/Dynamic_time_warping) (Dynamic Time Warping, DTW) 可用來比對不同觀測點的指數圖像,在容許時間偏移的條件下計算相似度。透過觀察哪個節點的指數最先抬升、哪些節點同步跟進,有機會反推異常源頭是在客戶端、骨幹網路還是伺服器端,進而將診斷從「是否異常」推進到「異常起源於何處」。
## 如何理解 `ping` 量到的是什麼
RTT 常由 [ping](https://man7.org/linux/man-pages/man8/ping.8.html) 或 [traceroute](https://man7.org/linux/man-pages/man8/traceroute.8.html) 測得,但在解讀結果時,必須先分清楚量到的是控制平面 (control plane) 反應,還是資料平面 (data plane) 轉送。
以下是 Cisco 文件中的典型例子。從 Router1 對 Router2 執行 `ping`:
```
Router1# ping 172.16.0.12
Sending 5, 100-byte ICMP Echos to 172.16.0.12:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/4/4 ms
```
當 Router2 啟用大量運算操作後再次執行:
```
Router1# ping 172.16.0.12
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 24/25/28 ms
```
這裡 RTT 顯著上升,反映的是 Router2 對送到本機的 ICMP Echo Request 回應變慢,也就是控制平面或裝置本身的處理負載增加。

若改成從 Router1 `ping` Router3,而封包需要穿越中間的 Router2:

```
Router1# ping 10.0.3.23
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 32/32/32 ms
```
此時即使 Router2 有額外負載,再次測試仍可能只看到小幅變化:
```
Router1# ping 10.0.3.23
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 32/32/36 ms
```
這個現象說明,送到裝置本身的探測流量與穿越裝置的轉送流量,可能走不同處理路徑,因此對 CPU 忙碌程度的敏感性不同。在 Cisco 文件的脈絡下,這可用來區分 process-switched traffic 與 through-router traffic;在較新的平台上,則常由 CEF 或其他資料平面機制負責。重點不是死記某個交換術語,而是要先釐清量測封包究竟打到哪個平面,否則 RTT 變化很容易被誤讀。
> 延伸閱讀:[瞭解 Ping 和 Traceroute 命令](https://www.cisco.com/c/zh_tw/support/docs/ios-nx-os-software/ios-software-releases-121-mainline/12778-ping-traceroute.html)
## 何時可以讓協定參考這些指數
指數圖像很適合做觀測、診斷與告警,但若要進一步影響通訊協定行為,仍需補上決策層設計,至少包括:
- 多長的時間窗才算成立
- 需要連續多少個樣本為陽性才觸發
- 門檻要固定還是隨基準分佈滾動更新
- 誤報與漏報的代價各自是什麼
例如,若指數第一次短暫抬升,就立刻讓傳輸控制進入強保守模式,可能對短流造成不必要的吞吐損失;但若完全忽略早期異常,又可能錯失壅塞前兆。較合理的作法,是讓指數先作為決策輸入之一,而不是唯一依據,再搭配傳輸層回饋,例如重傳、RTT 漂移與封包遺失事件,共同決定是否調整策略。
## 不同傳輸協定的影響
不同壅塞控制演算法會對量測指標產生不同的「背景行為」,若不加以區分,容易將演算法的正常探索誤判為網路異常。
[BBR](https://research.google/pubs/bbr-congestion-based-congestion-control/) 在穩態下會週期性地探測瓶頸頻寬與最低 RTT,探測階段的 RTT 抬升與吞吐量波動屬於演算法刻意製造的受控變動,而非網路壅塞。若陽性特徵的基準分佈涵蓋 BBR 的正常探測週期,這些波動會自然落在 ECDF 的中段,不至於觸發陽性;但若基準期間恰好缺少探測行為 (例如短連線),就可能產生誤報。相較之下,[CUBIC](https://en.wikipedia.org/wiki/CUBIC_TCP) 的視窗增長較平滑,探測造成的 RTT 抖動通常較小。因此,在部署指數圖像系統時,建議依據主要使用的壅塞控制演算法分別建立基準分佈,而非將所有流混在同一份 ECDF 中。
[QUIC](https://en.wikipedia.org/wiki/QUIC)/HTTP3 帶來另一層挑戰:由於 QUIC 標頭加密,中間裝置 (如防火牆、負載平衡器) 無法直接觀測連線層級的 RTT、重傳或壅塞視窗,傳統的被動量測手段因此失效。在這種情況下,指數圖像的資料來源必須改為端點自我診斷:客戶端或伺服器透過 QUIC recovery 狀態或實作內部統計 (如 `smoothed_rtt`、`latest_rtt`、`bytes_in_flight`) 自行計算陽性特徵,再透過應用層遙測匯出。這種端點驅動的架構雖然增加了部署成本,但也帶來優勢:端點擁有最完整的連線狀態,不必像中間裝置那樣從加密流量中推測。
## 實作上的資料來源
這套方法不依賴特定量測工具,只要能穩定取得每條流或每段路徑的時間序列資料即可。實作時可從下列來源擷取資料:
- 主動量測,例如 `ping`、`traceroute` 或週期性探測
- 被動量測,例如傳輸層統計、佇列長度、重傳次數與應用層延遲
- 現成工具匯出的遙測資料,例如阿里雲的 [TCP-RT](https://www.alibabacloud.com/help/en/alinux/user-guide/tcp-rt-configurations)
若要實際部署,建議把系統拆成三層:
1. 資料蒐集層,負責彙整原始量測
2. 特徵轉換層,負責計算 ECDF、時間窗統計與陽性特徵
3. 決策介面層,將指數圖像提供給告警系統、儀表板或通訊協定模組
這樣的分層可避免分析邏輯和傳輸控制強耦合,也較容易逐步驗證每一層的正確性。
## 工程實作架構
在現代 Linux 環境中,資料蒐集層可利用 [eBPF](https://ebpf.io/) 在核心層級高效擷取 TCP 統計資訊。不過,eBPF 只是可行選項之一,不是這套方法的必要前提;若部署條件受限,也可先從 `ss -i`、`tcp_info`、應用層遙測或現成監測代理程式取得資料。若採用 eBPF,通常會優先選擇較穩定的 hook,例如 tracepoint 或 sockops 程式類型,因為直接掛 `kprobe` 到 `tcp_rcv_established`、`tcp_retransmit_skb` 這類核心函式,雖然彈性高,但要自行承擔跨核心版本的維護成本。若需讀取核心內部型別或欄位,可搭配 [CO-RE](https://docs.ebpf.io/concepts/core/) 機制達成跨版本可攜;CO-RE 依賴目標核心提供 [BTF](https://docs.kernel.org/bpf/btf.html) (BPF Type Format) 資訊,若核心未啟用 BTF,則需改用其他適配方式。擷取的資料可經 BPF ring buffer 匯出至使用者空間,再交由自訂彙整程式處理;若只是教學或除錯,也可用 [bpftrace](https://github.com/bpftrace/bpftrace) 快速驗證觀測點是否合理,但它較適合探索,不是長期穩定蒐集管線的唯一選擇。
特徵轉換層需要在串流 (streaming) 環境中即時計算滑動視窗內的 ECDF。若系統規模較小,Python 搭配 asyncio 即可處理;若需要支撐大量並行流,可考慮 [Apache Flink](https://flink.apache.org/) 等串流框架,其內建的視窗語意與狀態管理可簡化 per-flow ECDF 的維護。關鍵設計決策包括:ECDF 的視窗長度 (太短會不穩定,太長會遲鈍)、更新頻率,以及是否需要針對不同路徑或服務類型維護獨立的基準分佈。
決策介面層可與 [Prometheus](https://prometheus.io/) 整合,將每個陽性特徵與組合指數匯出為 Gauge 型時序指標。在 [Grafana](https://grafana.com/) 儀表板中,建議將原始量測 (如 RTT、吞吐量) 與對應的指數圖像以相同時間軸疊加顯示,使工程師能直觀對照「哪段時間的指數抬升對應到哪些原始量測的變化」。告警規則則可直接參考指數值,例如「壅塞指數連續 30 秒超過門檻」觸發通知。
## 這套方法的限制
雖然以統計分佈建立指數圖像很實用,但仍有幾個限制必須明講:
- 若流量分佈快速漂移,歷史 ECDF 很快會失真
- 若樣本太少,尾端分位數會非常不穩定
- 若不同型態流量被混在同一基準內,對映函數會失去辨識力
- 若缺乏獨立驗證資料,很難知道指數抬升是否真的對應某種特定異常
因此,這套方法最適合被視為「資料驅動的診斷輔助工具」,而不是保證正確的黑箱判決器。它能幫助工程師更快縮小問題範圍,但最終仍要回到協定行為、路徑特性與實際量測結果做交叉驗證。
## 從人工規則到模型學習
本文目前的組合方式 (乘積或求和) 與冪次 $n$ 都由人工指定,屬於規則式 (rule-based) 設計。若累積了足夠的標記資料,例如已確認的壅塞事件或已知的封包遺失原因,則可進一步將陽性特徵作為機器學習模型的輸入。Random Forest 或簡單的神經網路可以學習各特徵的最佳組合權重,將「人工設計組合函數」演進為「模型學習組合權重」。
這並不取代前述的統計框架,反而是建立在它之上:統計對映負責將原始量測轉成方向一致、可比較的特徵 (feature engineering),機器學習則負責找出最有區別力的組合方式。兩者的分工也意味著,即使模型最終取代了人工規則,對映層的品質 (方向正確性、ECDF 穩定性、時間窗選擇) 仍然直接決定模型輸入的品質。
## 參數敏感度分析
本文的組合函數與對映函數涉及幾個關鍵人工參數。若採用最簡單的縮放式對映,參數是縮放因子 $\alpha$ 與冪次 $n$;若採用前述帶門檻的替代寫法,則還需考慮啟動門檻 $\tau$ 與放大量 $\beta$。這些參數的選擇都會直接影響誤報與漏報的比例。
若有標記好的異常事件 (即使是模擬產生的),可用 [ROC 曲線](https://en.wikipedia.org/wiki/Receiver_operating_characteristic) 評估不同 $n$ 值下的 true positive rate 與 false positive rate 之折衷;也可搭配 [PR 曲線](https://en.wikipedia.org/wiki/Precision_and_recall) (precision-recall curve) 觀察在異常事件稀少時的辨識品質。實務上,$n$ 越大,乘積形式對 $a_i$ 偏離 1 的放大效果越強,靈敏度越高但雜訊也越容易被放大。
若採用 $a_i = \alpha \cdot \text{ECDF}(x_i)$,則 $\alpha$ 的選擇可進一步走向動態策略:在高頻寬低延遲環境中,jitter 的正常變異範圍較小,$\alpha$ 可設得保守 (如 1.02);在跨洲長途鏈路上,RTT 本身變異較大,$\alpha$ 可能需要放寬 (如 1.15),以避免正常波動被誤判為陽性。一種做法是讓 $\alpha$ 隨 ECDF 的分佈寬度 (如四分位距) 自動調整,使門檻在不同環境下自動校準。
若採用帶門檻的替代寫法,則 $\tau$ 決定從哪個分位數開始把樣本視為陽性,$\beta$ 則決定超過門檻後的放大量。兩者可分別對應「何時啟動」與「啟動後放大多少」。例如,將 $\tau$ 設為 P95,可明確表示只有最高 5% 的尾端樣本才算陽性;再用 $\beta$ 控制這些陽性樣本在乘積中的權重。這種寫法的優點是語意較直觀,但仍需滿足前文提到的正值條件,並用標記資料驗證是否真的比單純的 $\alpha$ 縮放更穩健。
## 結語
將網路指標轉換成統一方向的陽性特徵,再用統計分佈與時間窗組合成指數圖像,是一種兼具可解釋性與可擴充性的做法。它的價值不在於把複雜網路簡化成單一分數,而在於讓多個原本難以比較的量測值,能在同一個判讀框架中協同工作。
若資料品質穩定、對映方向一致、時間窗設計合理,這種方法可有效提升異常辨識的效率,並為後續的告警與控制策略提供更可靠的輸入。相對地,若忽略分佈變化、錯置特徵方向,或把觀測工具直接當成閉迴路控制器,則很容易高估模型能力。統計方法真正的作用,不是替工程判斷背書,而是讓判斷建立在更清楚的證據上。