Kiểm soát lưu lượng trên Linux (tc): Hướng dẫn thực hành
12 phút đọc - 5 tháng 6, 2026

Kiểm soát băng thông, ưu tiên lưu lượng và định hình lưu lượng vào/ra trên Linux bằng tc. Cấu hình HTB, IFB, DSCP và fq_codel hoạt động trên các máy chủ thực tế.
Kiểm soát lưu lượng trên Linux (tc): Hướng dẫn thực hành
Lệnh tc cho phép bạn kiểm soát trực tiếp cách máy chủ xử lý lưu lượng mạng. Bạn có thể giới hạn băng thông cho từng dịch vụ, duy trì phản hồi của các phiên tương tác như SSH khi lưu lượng truyền tải hàng loạt tăng đột biến, đồng thời điều chỉnh cả lưu lượng đi và đến từ một công cụ duy nhất. Hướng dẫn này bao gồm các khái niệm cốt lõi, cách thiết lập HTB hoạt động, điều chỉnh lưu lượng vào bằng IFB, sắp xếp thứ tự ưu tiên dựa trên DSCP và cách gỡ lỗi khi gặp sự cố.
Cách tc hoạt động
Mỗi tc cấu hình đều được xây dựng từ bốn thành phần chính:
- qdisc (kỷ luật xếp hàng). Bộ lập lịch được gắn với giao diện mạng. Nó quyết định cách các gói tin được xếp vào hàng đợi và lấy ra khỏi hàng đợi.
- Class. Một phân nhóm bên trong qdisc có phân lớp. Hãy hình dung nó như một làn đường có giới hạn tốc độ riêng.
- Filter. Kiểm tra tiêu đề gói tin (địa chỉ IP, cổng, dấu hiệu) và phân loại từng gói tin vào một lớp.
- Hành động. Những gì xảy ra với một gói tin khi nó khớp với điều kiện: chuyển tiếp, loại bỏ, chuyển hướng.
Các thành phần này tạo thành một cây. Các gói tin đi vào tại qdisc gốc, đi qua các bộ lọc, được phân loại vào các lớp bởi một major:minor mã định danh, và cuối cùng được xếp vào hàng đợi tại qdisc lá để truyền đi.
Đối với bất kỳ trường hợp nào phức tạp hơn so với việc khớp dựa trên cổng, hãy đánh dấu các gói tin bằng iptables hoặc nftables trong bảng mangle, sau đó sử dụng fw bộ lọc trong tc để phân loại theo dấu hiệu. Cách này có khả năng mở rộng tốt hơn nhiều so với việc xâu chuỗi các quy tắc thô u32 cho từng loại lưu lượng.
Lưu lượng đi so với lưu lượng đến
Hướng lưu lượng rất quan trọng. Kernel có thể đệm và trì hoãn các gói tin đi, đây chính là yếu tố cho phép định hình lưu lượng thực sự. Các gói tin đến đã đi qua đường truyền trước khi bạn nhìn thấy chúng, do đó bạn chỉ có thể kiểm soát chúng (bỏ qua khi vượt ngưỡng) trừ khi bạn chuyển hướng chúng đến một thiết bị IFB trước.
| Tính năng | Ra | Nhập |
|---|---|---|
| Hướng | Ra | Vào |
| Điều chỉnh lưu lượng | Bản địa | Yêu cầu IFB |
| Kiểm soát | Được hỗ trợ | Được hỗ trợ |
| Ứng dụng điển hình | QoS, chia sẻ băng thông, điều chỉnh tốc độ | Giới hạn tốc độ, giảm thiểu DDoS cơ bản |
Các qdisc bạn sẽ thực sự sử dụng
- HTB (Hierarchical Token Bucket). Có phân lớp. Sử dụng khi bạn muốn đảm bảo băng thông tối thiểu cho mỗi dịch vụ với khả năng mượn dung lượng chưa sử dụng từ các lớp khác.
- TBF (Token Bucket Filter). Không phân lớp. Sử dụng khi bạn chỉ cần giới hạn toàn bộ giao diện ở một tốc độ duy nhất.
- fq_codel (Fair Queuing Controlled Delay). Kết hợp tính công bằng cho từng luồng với quản lý hàng đợi chủ động để loại bỏ hiện tượng bufferbloat. Đây là qdisc mặc định trong hầu hết các bản phân phối Linux kể từ systemd 217 và được cài đặt mặc định trên RHEL 9. Luôn gắn nó làm qdisc lá dưới các lớp HTB, nếu không một luồng tham lam duy nhất có thể chiếm dụng toàn bộ lớp.
Cài đặt tc trên máy chủ Linux
tc được cung cấp kèm theo gói iproute2. Trên Debian và Ubuntu, hãy cài đặt nó bằng lệnh apt-get install iproute2. Trên RHEL và các phiên bản phái sinh, yum install iproute. Bạn sẽ cần quyền root hoặc sudo.
Trước tiên, hãy xác định tên giao diện chính xác. Đặt tên giao diện sai là nguyên nhân phổ biến nhất khiến cấu hình không hoạt động mà không có thông báo lỗi:
ip link showKiểm tra các thông tin hiện có trên giao diện, bao gồm các chỉ số thời gian thực:
tc -s qdisc show dev eth0Xóa bất kỳ qdisc gốc nào hiện có trước khi áp dụng cấu hình mới, để tránh RTNETLINK answers: File exists lỗi:
tc qdisc del dev eth0 root 2>/dev/null || trueNếu bạn đang cập nhật một quy tắc hiện có thay vì bắt đầu từ đầu, hãy sử dụng replace thay vì add để thực hiện thao tác hoán đổi nguyên tử.
Các tính năng giảm tải phần cứng như TSO và GSO gộp các gói tin theo cách gây cản trở cho việc định hình lưu lượng. Hãy tắt chúng trên giao diện được định hình:
sudo ethtool -K eth0 tso off gso offĐặt fq_codel làm qdisc mặc định trên toàn hệ thống cho các giao diện mới:
sysctl -w net.core.default_qdisc=fq_codelĐối với các máy chủ bận rộn, hãy kết hợp nó với thuật toán kiểm soát tắc nghẽn BBR (kernel 4.9 trở lên). BBR duy trì thông lượng cao mà không làm tăng độ dài hàng đợi:
sysctl -w net.ipv4.tcp_congestion_control=bbrMột thói quen an toàn nếu bạn đang cấu hình một máy chủ từ xa qua SSH: mở một phiên thứ hai và chuẩn bị sẵn tc qdisc del dev eth0 root sẵn sàng để dán. Một quy tắc lọc sai có thể khiến bạn bị khóa truy cập ngay lập tức.
Điều chỉnh lưu lượng đi ra bằng HTB
HTB cho phép bạn đặt mức tối thiểu được đảm bảo (rate) và mức tối đa (ceil). Băng thông chưa sử dụng sẽ được phân bổ cho các dịch vụ cần thiết, theo thứ tự ưu tiên. Dưới đây là cấu hình ba tầng hoạt động cho đường truyền lên 1 Gbps.
Tạo qdisc HTB gốc. default 30 sẽ gửi bất kỳ gói tin nào chưa được phân loại vào lớp 1:30 thay vì để nó bỏ qua các quy tắc của bạn:
tc qdisc add dev eth0 root handle 1: htb default 30Giới hạn tổng thông lượng ở mức 900 Mbps. Luôn điều chỉnh thông lượng ở mức thấp hơn một chút so với dung lượng thực tế của liên kết, nếu không, hàng đợi sẽ hình thành trên bộ định tuyến hoặc modem đầu nguồn mà bạn không kiểm soát được:
tc class add dev eth0 parent 1: classid 1:1 htb rate 900mbit ceil 900mbitXác định các cấp độ dịch vụ. Các giá trị prio sẽ được ưu tiên sử dụng băng thông chưa sử dụng trước:
# High priority: web and API traffic
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 500mbit ceil 900mbit prio 1
# Medium priority: database replication
tc class add dev eth0 parent 1:1 classid 1:20 htb rate 300mbit ceil 900mbit prio 2
# Low priority: bulk and backup traffic
tc class add dev eth0 parent 1:1 classid 1:30 htb rate 100mbit ceil 900mbit prio 3Gắn fq_codel làm qdisc lá cho mỗi lớp để một luồng duy nhất không thể chiếm ưu thế trong cấp độ của nó:
tc qdisc add dev eth0 parent 1:10 handle 10: fq_codel
tc qdisc add dev eth0 parent 1:20 handle 20: fq_codel
tc qdisc add dev eth0 parent 1:30 handle 30: fq_codelBây giờ hãy phân loại lưu lượng. Đối với việc khớp cổng đơn giản, u32 là nhanh nhất:
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
match ip dport 443 0xffff flowid 1:10Đối với bất kỳ trường hợp nào có trạng thái, hãy đánh dấu trong iptables và so khớp dấu đó với fw:
iptables -t mangle -A OUTPUT -p tcp --dport 5432 -j MARK --set-mark 2
tc filter add dev eth0 protocol ip parent 1:0 prio 2 handle 2 fw flowid 1:20Điều chỉnh lưu lượng truy cập đến bằng IFB
Bạn không thể định hình lưu lượng vào một cách nguyên bản vì khi gói tin đến, nó đã sử dụng hết băng thông của bạn. Giải pháp thay thế là chuyển hướng lưu lượng vào sang giao diện ảo Intermediate Functional Block (IFB), nơi nhân hệ điều hành xử lý nó như lưu lượng ra và cho phép bạn áp dụng các qdiscs phân loại.
Tải mô-đun và kích hoạt giao diện:
modprobe ifb numifbs=1
ip link set dev ifb0 upThêm một qdisc vào giao diện vật lý và chuyển hướng mọi thứ đến ifb0:
tc qdisc add dev eth0 ingress handle ffff:
tc filter add dev eth0 parent ffff: protocol all u32 \
match u32 0 0 action mirred egress redirect dev ifb0Từ đây, ifb0 nó sẽ hoạt động giống như bất kỳ giao diện nào khác. Áp dụng cây HTB của bạn vào nó chính xác như cách bạn làm với lưu lượng ra:
tc qdisc add dev ifb0 root handle 1: htb default 30
tc class add dev ifb0 parent 1: classid 1:1 htb rate 900mbit ceil 900mbit
tc class add dev ifb0 parent 1:1 classid 1:10 htb rate 500mbit ceil 900mbit prio 1Ưu tiên lưu lượng bằng DSCP
DSCP (Differentiated Services Code Point) gắn thẻ các gói tin bằng một giá trị 6 bit trong byte TOS, do đó các tc bộ lọc của bạn có thể phân loại theo thẻ thay vì phải tìm kiếm các cổng trong bộ quy tắc. Khi so khớp DSCP trong tc, hãy dịch giá trị sang trái 2 bit. DSCP EF (46) sẽ trở thành 0xb8. Mặt nạ 0xfc tách 6 bit DSCP khỏi 2 bit ECN.
Một bản ánh xạ mặc định hợp lý cho các tải công việc máy chủ:
| Loại lưu lượng | DSCP | TOS hex | Ví dụ |
|---|---|---|---|
| Tương tác | EF | 0xb8 | SSH, DNS, VoIP |
| Doanh nghiệp | AF41 | 0x88 | HTTP, HTTPS, API |
| Hàng loạt | CS1 | 0x20 | Sao lưu, FTP, cập nhật gói phần mềm |
| Nỗ lực tối đa | CS0 | 0x00 | Tất cả các trường hợp khác |
Đánh dấu các gói tin đi trong iptables trước khi chúng đi qua tc bộ lọc:
iptables -t mangle -A OUTPUT -p tcp --dport 22 -j DSCP --set-dscp 46Sau đó, so khớp thẻ trong tc và định tuyến chúng đến lớp HTB phù hợp:
# EF (SSH, VoIP) goes to the high-priority class
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
match ip tos 0xb8 0xfc flowid 1:10
# AF41 (web traffic) goes to the medium class
tc filter add dev eth0 protocol ip parent 1:0 prio 2 u32 \
match ip tos 0x88 0xfc flowid 1:20
# CS1 (bulk) goes to the low-priority class
tc filter add dev eth0 protocol ip parent 1:0 prio 3 u32 \
match ip tos 0x20 0xfc flowid 1:30Giám sát và khắc phục sự cố
Ba lệnh bạn sẽ sử dụng thường xuyên:
tc -s qdisc show dev eth0
tc -s class show dev eth0
tc -s filter show dev eth0Theo dõi dropped và overlimits các chỉ số. Các gói tin bị bỏ qua có nghĩa là hàng đợi đã bão hòa; các giá trị vượt ngưỡng có nghĩa là bạn đã đạt đến giới hạn của lớp và nhân hệ điều hành phải trì hoãn hoặc loại bỏ lưu lượng. Để xem trực tiếp:
watch -n 1 'tc -s class show dev eth0'Thêm -d cho các tham số nội bộ (target, interval, quantum) và -j cho đầu ra JSON nếu bạn đang chuyển dữ liệu vào hệ thống theo dõi chỉ số. Kết hợp với ss -tin để xem ước tính RTT và số lần truyền lại ở lớp TCP.
Hầu hết các sự cố đều thuộc một danh sách ngắn:
| Triệu chứng | Nguyên nhân có thể | Cách khắc phục |
|---|---|---|
RTNETLINK answers: File exists | qdisc gốc đã được cấu hình | tc qdisc del dev eth0 root đầu tiên |
| Các quy tắc được áp dụng nhưng lưu lượng không bị giới hạn | Giao diện sai, hoặc TSO/GSO vẫn đang hoạt động | Xác nhận bằng ip link show, vô hiệu hóa các tính năng offload bằng ethtool -K |
| Bộ lọc không bao giờ khớp | Cú pháp cổng/IP hoặc cách căn chỉnh mặt nạ không đúng | Thêm một hành động đối phó và kiểm tra số lần trúng trong tc -s filter show |
| Các quy tắc biến mất sau khi khởi động lại | Cấu hình chỉ tồn tại trong bộ nhớ | Đóng gói vào một tập lệnh và gọi từ systemd hoặc bộ điều phối NetworkManager |
| Độ trễ cao trên lưu lượng ưu tiên | Không có qdisc lá, hoặc mức bùng nổ quá thấp | Gán fq_codel vào các lớp leaf, tăng burst |
Nếu bạn vô tình bị khóa ngoài do cấu hình sai, việc khôi phục rất đơn giản:
tc qdisc del dev eth0 roottc không thể tạo ra băng thông mà bạn không có, nhưng trên một đường truyền lên được cung cấp đầy đủ, điều này tạo ra sự khác biệt giữa hiệu suất có thể dự đoán được và một máy chủ bị sập ngay khi một khách hàng bắt đầu một quá trình truyền tải dữ liệu lớn. Nếu bạn cần băng thông thô và sự tự do để định hình nó theo ý muốn, hãy xem xét các máy chủ chuyên dụng của FDC.

Hướng dẫn sử dụng iperf3: Kiểm tra tốc độ mạng trên Linux và Windows
Cài đặt iperf3, thực hiện các bài kiểm tra băng thông và điều chỉnh bộ đệm TCP để có kết quả chính xác trên Linux và Windows. Bao gồm các bài kiểm tra UDP, hai chiều và 10GbE+.
10 phút đọc - 7 tháng 5, 2026
Các cấu hình được tối ưu hóa cho việc tối ưu hóa tải công việc trên máy chủ Linux
16 phút đọc - 9 tháng 6, 2026

Bạn có thắc mắc hoặc cần giải pháp tùy chỉnh?
Các tùy chọn linh hoạt
Phạm vi toàn cầu
Triển khai ngay lập tức
Các tùy chọn linh hoạt
Phạm vi toàn cầu
Triển khai ngay lập tức