如何依時段設定伺服器頻寬限制

在一天之中手動調整頻寬上限會浪費你的時間。你可能過早限速,導致尖峰時段發生壅塞;也可能在夜間仍維持較高限制,從而浪費頻寬資源。這種不一致會損害網站效能與頁面載入速度。
你可以自動設定伺服器頻寬限制的切換。使用 Linux 流量整形工具 tc 搭配 cron 排程,即可針對不同時段設定不同的限制。
本指南將帶你一步步完成。你將辨識網路介面、撰寫 tc 規則、透過 cron 實現自動化,並測試結果。正確的設定可以在業務繁忙時降低伺服器回應時間。當壅塞下降時,伺服器的初始回應時間也會改善。更快的伺服器回應時間,代表訪客能獲得更好的使用體驗。
現在就開始吧。
前置條件與工具
在建立依時段的限制之前,你需要先做好兩件事:辨識你的網路介面,並選擇合適的流量整形工具。正確設定能在流量高峰時降低伺服器回應時間。把這些基礎環節處理好,才能更有效率地控管伺服器頻寬。
辨識網路介面與頻寬使用情況
你可以使用以下任一指令來查找網路介面:
ip a—— 顯示所有網路介面詳細資訊及其 IP 位址。ip link show—— 顯示介面狀態與 MAC 位址。nmcli device status—— 列出 NetworkManager 管理的裝置狀態。
你的網路介面通常是 eth0 或 ens33。請選擇綁定公網 IP 的那個介面。
接著,使用 nload 測量實際頻寬使用情況。這個工具會讀取 /proc/net/dev 中的計數器,不會擷取封包,因此額外負擔很低。你需要了解網站的流量模式。它會以 ASCII 圖形顯示進站與出站流量,同時呈現目前、平均、最小、最大速率以及總位元組數。
nload會透過讀取/proc/net/dev取得流量計數器。這種方式負擔極低,而且執行時不需要 root 權限。
執行 nload eth0 來觀察頻寬使用情況。精確的測量有助於改善伺服器回應時間。利用這些資料來決定尖峰與離峰時段的網路頻寬限制。了解目前的實際消耗,才能設定出有效的頻寬上限。
選擇流量整形工具
tc 搭配 HTB(Hierarchical Token Bucket,階層式令牌桶)是 Linux 上的標準解決方案。HTB 允許你為不同流量類別設定保證速率與上限速率。在壅塞期間使用 HTB,有助於維持良好的伺服器回應時間。你可以讓 SSH 的優先順序高於 HTTP,或是為管理子網路配置更高優先順序。下表展示了其主要使用情境:
使用情境 | 說明 |
|---|---|
容量分配 | 設定總頻寬上限,並在多個類別之間分配保證速率與上限速率。 |
連接埠優先順序 | 將 SSH 設為高優先順序,HTTP 設為中優先順序,FTP 設為低優先順序。 |
子網路優先順序 | 為特定子網路來源的流量賦予更高優先順序。 |
應用程式流量整形 | 透過 iptables 標記封包,再根據這些標記進行過濾與控管。 |
如果你的規則較簡單,也可以使用 TBF(Token Bucket Filter,令牌桶過濾器)。它不區分類別,只會對所有流量施加單一速率限制。其他替代方案包括 iptables --limit 和 cgroups。但在依時段切換規則的情境下,tc 搭配 HTB 仍提供最高的彈性。
完成這些前置準備後,你就能更有效降低伺服器回應時間。現在你已經知道如何辨識網路介面並選擇適合的工具。下一節將說明如何撰寫 tc 規則。
使用 tc 設定伺服器頻寬限制
現在開始撰寫實際規則。本節將說明兩種主要的佇列規則,並示範如何在不同時段設定不同頻寬上限。你將學會如何根據每日流量模式,自動切換伺服器頻寬限制。
了解 HTB 與 TBF 佇列規則
HTB 是 Hierarchical Token Bucket(階層式令牌桶)的縮寫。它將頻寬組織成一棵類別樹,每個類別都擁有自己的令牌桶。令牌會以固定速率產生,只有當令牌足夠時,資料封包才能被送出。這種機制能精準執行你的頻寬限制。
HTB 將簡單令牌桶擴展為階層式結構。你可以建立父類別與子類別,每個類別都擁有自己的參數。下表說明兩個關鍵參數:
參數 | 說明 |
|---|---|
rate | 某個類別的保證最低頻寬 |
ceil | 該類別可使用的最大頻寬上限,包括借用頻寬 |
Borrowing |
|
rate 參數確保某個類別至少獲得這部分頻寬;ceil 參數則定義絕對上限。當某個類別需要超過其 rate 的頻寬時,它會向父類別借用。借用會持續到該類別達到自己的 ceil,或達到父類別的 ceil 為止。這種設計可以更有效率地利用未被占用的頻寬容量。
來看一個簡單例子。葉節點類別 #10 的 rate 為 200 kbps,ceil 為 400 kbps;葉節點類別 #20 的 rate 為 200 kbps,ceil 也為 200 kbps。類別 #10 最多可以再借用 200 kbps,而類別 #20 則完全不能借用,因為它的 rate 等於 ceil。
TBF 是 Token Bucket Filter(令牌桶過濾器)的縮寫。它不區分類別,只套用單一速率限制。對於只需要為所有流量設定統一上限的簡單情境,TBF 非常合適。而對於依時段切換規則的需求,HTB 更具彈性,因為你可以調整各個獨立類別。
HTB 的運作分成兩個階段。首先,它滿足每個子佇列的保證速率;其次,它允許子類別向父類別借用令牌。這種階層式滿足機制可確保關鍵流量始終獲得最低保障,而優先順序較低的流量則能在鏈路空閒時使用剩餘頻寬。
為尖峰與離峰時段撰寫規則
你將建立兩組規則:一組用於尖峰時段,另一組用於離峰時段。先從尖峰時段開始。假設你想將頻寬上限設為 10 Mbps,可使用以下指令:
tc qdisc add dev eth0 root handle 1: htb default 10
tc class add dev eth0 parent 1: classid 1:1 htb rate 10mbit ceil 10mbit
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 8mbit ceil 10mbit第一條指令建立根佇列;第二條指令定義父類別;第三條指令建立子類別。你也可以繼續新增更多子類別,以符合不同連接埠群組的頻寬控管需求。
對於離峰時段,如果你想將頻寬上限提高到 50 Mbps,請先刪除舊規則,再套用新設定:
tc qdisc del dev eth0 root
tc qdisc add dev eth0 root handle 1: htb default 10
tc class add dev eth0 parent 1: classid 1:1 htb rate 50mbit ceil 50mbit
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 40mbit ceil 50mbitrate 參數代表保證頻寬,ceil 參數代表最大頻寬上限。當鏈路仍有空閒容量時,伺服器可以在高於 rate 的水準上進行突發傳輸。這種借用機制有助於在突發流量出現時改善伺服器回應時間。
實際測試顯示,HTB 表現良好。當兩個用戶端同時在 100 mbit 鏈路上傳輸時,每個用戶端大約可獲得 50–59 Mbits/sec;當其中一個用戶端停止後,另一個用戶端會提升至約 75–77 Mbits/sec。這表示借用機制確實如設計般運作。
CAKE 也是另一種可選方案。它預設提供按主機公平分配頻寬的能力。在啟用 triple-isolate 時,一個只有單一連線的用戶端可獲得 50 mbit;另一個擁有十條連線的用戶端,其總頻寬也同樣為 50 mbit。若不進行流量整形,每個用戶端的頻寬可能會在 6–14 mbit 之間波動,而且延遲會明顯惡化。合理的流量整形能顯著降低伺服器回應時間。
這些規則可以有效控管伺服器頻寬。你可以依據實際測量到的使用情況調整數值。下一節將介紹如何使用 cron 自動化這些切換。
使用 Cron 實現自動化
手動切換規則,違背了依時段管理頻寬的初衷。你需要自動化,而 cron 能可靠地完成這項任務。它會在你指定的精確時間執行 tc 指令。本節將說明如何建立腳本並正確設定排程。
為規則撰寫腳本
使用單一腳本可以讓整個流程更簡單。你可以在腳本中定義多個函式,每個函式套用不同的一組 tc 規則,然後在適當時間呼叫對應函式。
建立一個名為 /usr/local/bin/bandwidth-limits.sh 的檔案。腳本中包含兩個主要函式:一個套用尖峰時段限速,另一個套用離峰時段限速。每個函式都會先刪除現有規則,再新增新規則。
#!/bin/bash
apply_peak() {
tc qdisc del dev eth0 root 2>/dev/null
tc qdisc add dev eth0 root handle 1: htb default 10
tc class add dev eth0 parent 1: classid 1:1 htb rate 10mbit ceil 10mbit
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 8mbit ceil 10mbit
}
apply_offpeak() {
tc qdisc del dev eth0 root 2>/dev/null
tc qdisc add dev eth0 root handle 1: htb default 10
tc class add dev eth0 parent 1: classid 1:1 htb rate 50mbit ceil 50mbit
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 40mbit ceil 50mbit
}
case "$1" in
peak) apply_peak ;;
offpeak) apply_offpeak ;;
esac使用 chmod +x /usr/local/bin/bandwidth-limits.sh 為腳本加入可執行權限。先手動測試它。執行 sudo /usr/local/bin/bandwidth-limits.sh peak,再使用 tc -s qdisc ls dev eth0 檢查目前規則。你應該會看到 10mbit 的速率設定。這個驗證步驟能避免後續出現意外問題。
這個腳本接受一個參數,也就是 peak 或 offpeak。這種設計讓你的 cron 條目更簡潔、更易讀,也不需要在 crontab 中重複冗長的 tc 指令。
使用 Cron 排程腳本
Cron 會從名為 crontab 的檔案中讀取排程。你可以使用 crontab -e 進行編輯。每一行包含五個時間欄位與一個指令,欄位依序代表:分鐘、小時、每月第幾日、月份、星期幾。
你的排程需要兩筆紀錄:一筆在 9:00 切換為尖峰規則,另一筆在 17:00 切換為離峰規則。設定如下:
0 9 * * * /usr/local/bin/bandwidth-limits.sh peak
0 17 * * * /usr/local/bin/bandwidth-limits.sh offpeak
第一筆會在每天 9:00 執行,第二筆會在每天 17:00 執行。如果你將這些行加入 root 的 crontab,cron 就會以 root 權限執行腳本。請使用 sudo crontab -e 完成這項設定。
你也可以把這種方式擴充到更複雜的排程。例如,如果週末的尖峰時段開始時間不同,就可以新增更多具有不同小時值的條目。Cron 會各自獨立執行它們。
多個特定時間區間可以用逗號指定(例如
1,2,3)。下面這行指令會在第 1、2、3 個小時內,每隔 5 分鐘輸出一次「hello world」(也就是從 01:00、01:05、01:10 一直到 03:55)。*/5 1,2,3 * * * echo hello world
這種逗號語法有助於合併條目。例如,如果你想在 8:00、12:00 和 17:00 套用尖峰限制,可以寫成 0 8,12,17 * * *,而不必拆成三行。這樣你的 crontab 會更整齊,也更容易稽核。
編輯完 crontab 後,請進行驗證。執行 crontab -l 查看目前排程,確認兩筆紀錄都已正確加入。接著等待下一個排程時間觀察變化,或也可以先手動執行腳本測試各個函式,再正式依賴 cron 自動執行。
自動化能把人為錯誤從頻寬管理中排除。你的伺服器會在無需人工介入的情況下,自動套用正確的頻寬上限。這種一致性會直接改善尖峰時段的伺服器回應時間。由於壅塞受到控制,使用者感受到的延遲也會更少。伺服器回應時間能在全天維持更穩定,夜間也不會再無謂浪費頻寬資源。你的伺服器將可實現全天候高效率運作。
測試與最佳化,以降低伺服器回應時間
測試可以確認你的設定是否確實生效。本節將說明如何驗證規則並探索替代方案。這些步驟有助於你在高負載情況下,進一步降低伺服器回應時間。
使用 iperf 驗證頻寬限制
iperf3 可以測量伺服器的實際吞吐能力。先使用 iperf3 -s 啟動監聽模式,再由用戶端執行 iperf3 -c <host> 發起測試。你可以使用 --server-bitrate-limit #[KMG][/#] 選項測試你的頻寬上限。這個工具會顯示在 tc 規則作用下的真實傳輸速率。請將測試結果與你的目標限制進行比較;如果差異明顯,通常代表設定存在問題。
合理的頻寬限制能透過控制壅塞來降低伺服器回應時間。當資料到達速度超過網路可承載能力時,封包會進入輸出佇列,佇列延遲會沿著多個網路節點逐步累積。路由器緩衝區被填滿後會發生丟包,TCP 會偵測到遺失並將壅塞視窗縮減 50%。這種流量控制機制會降低資料傳輸速率,進而增加伺服器回應時間。
不過,壅塞對伺服器回應時間的影響並不是絕對的,因為伺服器處理時間本身也可能佔據主導地位。舉例來說,總回應時間為 5 秒,其中伺服器處理耗時 4.8 秒,網路部分僅占 0.2 秒,也就是 4%。在這種情況下,即使完全消除網路延遲,也未必會帶來明顯改善。你可以在套用限速前後使用 ping 測量延遲,以驗證實際效果。
當網路流量需求超過可用容量時,就會發生網路壅塞。這會導致資料傳輸變慢、延遲升高,並可能造成資料遺失。更高的延遲會迫使系統進行重傳,並延後請求與回應的傳遞。
替代方案:防火牆與備份軟體
你不一定只能依賴 tc 規則。Palo Alto 防火牆提供具備依時間排程功能的 QoS 設定檔。透過其 schedule(排程)分頁,你可以依一天中的不同時間套用不同的服務品質策略。例如,可以在上午 7 點到中午 12 點,以及下午 1 點到晚上 7 點限制 YouTube,只在午休時段允許使用者以 class4 類別觀看影片。這種方式適用於網路邊界層級的控管。
備份軟體同樣提供定時限速功能。例如 Arcserve 可讓你在備份時段期間設定頻寬上限。這類工具可以管理伺服器在資料傳輸過程中的出站流量。
透過這些規則來管理網站流量,有助於提升頁面載入速度。當壅塞下降時,伺服器初始回應時間也會改善。你還可以支撐更高的 rps 與更高的 maximum requests per second。請持續監控伺服器回應時間,並觀察在不同頻寬上限下,伺服器處理傳入請求的表現。每次調整排程後都測試一次伺服器回應時間,再根據真實資料持續最佳化。這樣的測試與調校循環,能持續改善伺服器回應時間。
你首先辨識了網路介面,接著為尖峰與離峰時段設定了 tc 規則,再透過 cron 自動切換這些限制,最後使用 iperf 驗證吞吐量是否符合預期。
這種動態方法可以讓你在無需手動操作的情況下完成伺服器頻寬限制切換。合理的頻寬上限能在業務高峰時控制伺服器壅塞。當佇列維持較短時,伺服器回應時間就會改善。更快的伺服器回應時間,能讓訪客在流量高峰期間保持良好體驗。這些調整能有效降低高負載時的伺服器回應時間。
你可以根據自身門檻調整這些範例。例如,白天設定為 20 Mbps,夜間設定為 100 Mbps。每次修改後都要監控伺服器回應時間,並依據實際流量資料進行調校。透過適當的定時排程,伺服器就能更平穩地處理請求。
現在就執行 tc -s qdisc ls dev eth0,然後在今晚設定你的第一次定時切換吧。
常見問題
伺服器重新開機後,我設定的頻寬限制會怎樣?
你的 tc 規則會在伺服器重新開機後消失,而 cron 不會自動重新套用它們。請新增一條帶有 @reboot 的 cron 紀錄,在系統啟動時執行腳本。這樣可以確保伺服器在啟動後立即套用正確的頻寬限制,從而維持穩定的伺服器回應時間。
我該如何驗證頻寬限制是否真的生效?
執行 tc -s qdisc ls dev eth0 查看目前啟用的規則,再使用 iperf3 測試實際吞吐量,並將結果與你預期的頻寬上限進行比較。測試可以幫助你在高負載下更有效降低伺服器回應時間。當佇列維持較短時,伺服器回應時間也會隨之改善。
如果週末的尖峰時段和週間不同,該怎麼辦?
你可以為週末另外新增更多 cron 條目。使用不同的行分別指定平日與週末即可。Cron 支援星期欄位,你可以使用 1-5 表示平日,6-0 表示週末。這樣的彈性設定能讓伺服器在整週內都維持穩定的回應時間。
我可以設定超過兩個時段嗎?
可以。你只需在腳本中新增更多函式,例如用於中午或晚間的不同頻寬上限,並在 cron 中加入對應的排程條目。每個函式負責套用一套不同的 tc 規則,伺服器會在每個排程時間點自動切換。每次切換後,請持續監控伺服器回應時間。
