#server-performance

Kontrola ruchu w systemie Linux (tc): praktyczny przewodnik

12 min czytania - 5 czerwca 2026

hero section cover

Kontrola przepustowości, ustalanie priorytetów ruchu oraz kształtowanie ruchu przychodzącego i wychodzącego w systemie Linux za pomocą narzędzia tc. Działające konfiguracje HTB, IFB, DSCP i fq_codel dla serwerów Real.

Kontrola ruchu w systemie Linux (tc): praktyczny przewodnik

Polecenie tc pozwala na bezpośrednią kontrolę nad sposobem, w jaki serwer obsługuje ruch sieciowy. Można ograniczyć przepustowość dla poszczególnych usług, zapewnić płynność sesji interaktywnych, takich jak SSH, nawet podczas gwałtownych wzrostów transferu danych, a także kształtować zarówno ruch wychodzący, jak i przychodzący za pomocą jednego narzędzia. Niniejszy przewodnik obejmuje podstawowe pojęcia, działającą konfigurację HTB, kształtowanie ruchu przychodzącego za pomocą IFB, ustalanie priorytetów na podstawie DSCP oraz sposoby debugowania w przypadku wystąpienia problemów.


 

Jak działa tc

Każda tc konfiguracja składa się z czterech elementów:

  • qdisc (dyscyplina kolejkowania). Harmonogram przypisany do interfejsu sieciowego. Decyduje on o tym, w jaki sposób pakiety są umieszczane w kolejce i z niej pobierane.
  • Klasa. Podział wewnątrz qdisc z podziałem na klasy. Można to porównać do pasa ruchu z własnym ograniczeniem prędkości.
  • Filtr. Sprawdza nagłówki pakietów (adresy IP, porty, oznaczenia) i przypisuje każdy pakiet do odpowiedniej klasy.
  • Akcja. Co dzieje się z pakietem po dopasowaniu: przekazanie, odrzucenie, przekierowanie.

Elementy te tworzą drzewo. Pakiety wchodzą do qdiscu korzeniowego, trafiają do filtrów, są sortowane do klas przez major:minor identyfikatora, a na koniec trafiają do kolejki w qdiscu liściowym w celu transmisji.

W przypadku operacji bardziej złożonych niż dopasowanie oparte na porcie należy oznaczyć pakiety za pomocą iptables lub nftables w tabeli mangle, a następnie użyć fw filtru w tc w celu klasyfikacji według oznaczenia. Skaluje się to znacznie lepiej niż łańcuchowanie surowych u32 reguł dla każdego typu ruchu.

Ruch wychodzący a ruch przychodzący

Kierunek ma znaczenie. Jądro może buforować i opóźniać pakiety wychodzące, co umożliwia rzeczywiste kształtowanie ruchu. Pakiety przychodzące przeszły już przez łącze, zanim je zobaczysz, więc możesz je jedynie monitorować (odrzucać powyżej progu), chyba że najpierw przekierujesz je do urządzenia IFB.

FunkcjaRuch wychodzącyRuch przychodzący
KierunekWychodzącePrzychodzące
KształtowanieNatywnyWymaga IFB
KontrolaObsługiwaneObsługiwane
Typowe zastosowanieQoS, podział przepustowości, regulacja przepustowościOgraniczanie przepustowości, podstawowa ochrona przed atakami DDoS

Qdiscy, z których faktycznie będziesz korzystać

  • HTB (Hierarchical Token Bucket). Klasowy. Używaj go, gdy chcesz zagwarantować minimalną przepustowość dla każdej usługi z możliwością pożyczenia niewykorzystanej przepustowości z innych klas.
  • TBF (Token Bucket Filter). Bezklasowy. Używaj go, gdy chcesz po prostu ograniczyć przepustowość całego interfejsu do jednej wartości.
  • fq_codel (Fair Queuing Controlled Delay). Łączy sprawiedliwość na poziomie poszczególnych przepływów z aktywnym zarządzaniem kolejkami, aby wyeliminować zjawisko „bufferbloat”. Jest to domyślny qdisc w większości dystrybucji Linuksa od wersji systemd 217 i jest dostarczany jako domyślny w RHEL 9. Zawsze należy go dołączać jako qdisc końcowy pod klasami HTB, w przeciwnym razie pojedynczy „chciwy” przepływ może zmonopolizować całą klasę.

Konfiguracja programu tc na serwerze z systemem Linux

tc jest dostarczany wraz z pakietem iproute2. W systemach Debian i Ubuntu należy go zainstalować za pomocą polecenia apt-get install iproute2. W systemie RHEL i jego pochodnych yum install iproute. Potrzebne będą uprawnienia roota lub sudo.

Najpierw sprawdź prawidłową nazwę interfejsu. Błędne nazwanie interfejsu jest najczęstszą przyczyną, dla której konfiguracja nie przynosi żadnych efektów:

ip link show

Sprawdź, co już znajduje się na interfejsie, w tym aktualne liczniki:

tc -s qdisc show dev eth0

Przed zastosowaniem nowej konfiguracji usuń wszelkie istniejące qdisc typu root, aby uniknąć RTNETLINK answers: File exists błędów:

tc qdisc del dev eth0 root 2>/dev/null || true

Jeśli aktualizujesz istniejącą regułę, a nie zaczynasz od zera, użyj replace zamiast add , aby zapewnić atomową zamianę.

Odciążanie sprzętowe, takie jak TSO i GSO, grupuje pakiety w sposób, który zakłóca kształtowanie ruchu. Należy je wyłączyć na interfejsie, na którym stosowane jest kształtowanie ruchu:

sudo ethtool -K eth0 tso off gso off

Ustaw fq_codel jako domyślny qdisc dla nowych interfejsów w całym systemie:

sysctl -w net.core.default_qdisc=fq_codel

W przypadku obciążonych serwerów połącz to z algorytmem kontroli przeciążenia BBR (jądro 4.9+). BBR utrzymuje wysoką przepustowość bez wydłużania kolejek:

sysctl -w net.ipv4.tcp_congestion_control=bbr

Jedna z zasad bezpieczeństwa podczas konfigurowania zdalnego urządzenia przez SSH: otwórz drugą sesję i przygotuj tc qdisc del dev eth0 root gotowy do wklejenia. Zła reguła filtrująca może natychmiast zablokować dostęp.

Kształtowanie ruchu wychodzącego za pomocą HTB

HTB pozwala przypisać każdej usłudze gwarantowaną wartość minimalną (rate) oraz limit maksymalny (ceil). Niewykorzystana przepustowość trafia do tego, kto jej potrzebuje, zgodnie z kolejnością priorytetów. Oto działająca konfiguracja trójwarstwowa dla łącza w górę o przepustowości 1 Gbps.

Utwórz główny qdisc HTB. default 30 wysyła każdy niesklasyfikowany pakiet do klasy 1:30 zamiast pozwolić mu ominąć twoje reguły:

tc qdisc add dev eth0 root handle 1: htb default 30

Ogranicz całkowitą przepustowość do 900 Mbps. Zawsze kształtuj przepustowość nieco poniżej rzeczywistej przepustowości łącza, w przeciwnym razie kolejka utworzy się na routerze lub modemie upstream, nad którym nie masz kontroli:

tc class add dev eth0 parent 1: classid 1:1 htb rate 900mbit ceil 900mbit

Zdefiniuj poziomy usług. Niższe prio wartości otrzymują w pierwszej kolejności niewykorzystaną przepustowość:

# 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 3

Dołącz fq_codel jako qdisc typu „leaf” do każdej klasy, aby pojedynczy strumień nie zdominował swojej klasy:

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_codel

Teraz sklasyfikuj ruch. W przypadku prostego dopasowywania portów u32 jest najszybsze:

tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
  match ip dport 443 0xffff flowid 1:10

W przypadku wszelkich operacji stanowych należy oznaczyć w iptables i dopasować oznaczenie do 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

Kształtowanie ruchu przychodzącego za pomocą IFB

Nie można natywnie kształtować ruchu przychodzącego, ponieważ w momencie dotarcia pakietu wykorzystał on już przepustowość. Rozwiązaniem jest przekierowanie ruchu przychodzącego do wirtualnego interfejsu Intermediate Functional Block (IFB), gdzie jądro traktuje go jako ruch wychodzący i pozwala na zastosowanie dyskretów klasowych.

Załaduj moduł i uruchom interfejs:

modprobe ifb numifbs=1
ip link set dev ifb0 up

Dodaj qdisc przychodzący do interfejsu fizycznego i przekieruj cały ruch do 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 ifb0

Od tego momentu ifb0 zachowuje się jak każdy inny interfejs. Zastosuj do niego drzewo HTB dokładnie tak, jak w przypadku ruchu wychodzącego:

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

Priorytetyzacja ruchu za pomocą DSCP

DSCP (Differentiated Services Code Point) oznacza pakiety 6-bitową wartością w bajcie TOS, dzięki czemu tc filtry mogą klasyfikować na podstawie znacznika, zamiast przeszukiwać porty w całym zestawie reguł. Podczas dopasowywania DSCP w tc, przesuń wartość o 2 bity w lewo. DSCP EF (46) staje się 0xb8. Maska 0xfc oddziela 6 bitów DSCP od 2 bitów ECN.

Rozsądne domyślne mapowanie dla obciążeń serwerowych:

Typ ruchuDSCPTOS (szesnastkowo)Przykłady
InteraktywnyEF0xb8SSH, DNS, VoIP
BiznesAF410x88HTTP, HTTPS, interfejsy API
HurtowoCS10x20Kopie zapasowe, FTP, aktualizacje pakietów
Najlepsze możliweCS00x00Wszystko inne

Oznacz pakiety wychodzące w iptables, zanim trafią do twoich tc filtry:

iptables -t mangle -A OUTPUT -p tcp --dport 22 -j DSCP --set-dscp 46

Następnie dopasuj ten tag w tc i przekieruj je do odpowiedniej klasy HTB:

# 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:30

Monitorowanie i rozwiązywanie problemów

Trzy polecenia, z których będziesz korzystać na co dzień:

tc -s qdisc show dev eth0
tc -s class show dev eth0
tc -s filter show dev eth0

Obserwuj dropped i overlimits liczniki. Utracone pakiety oznaczają, że kolejka jest przepełniona; przekroczenie limitów oznacza, że osiągnąłeś pułap klasy, a jądro musiało opóźnić lub odrzucić ruch. Aby uzyskać podgląd na żywo:

watch -n 1 'tc -s class show dev eth0'

Dodaj -d dla parametrów wewnętrznych (target, interval, quantum) oraz -j dla wyjścia JSON, jeśli przekierowujesz dane do stosu metryk. Połącz to z ss -tin , aby zobaczyć szacunki RTT i retransmisje na warstwie TCP.

Większość awarii można zaklasyfikować do kilku typów:

ObjawPrawdopodobna przyczynaRozwiązanie
RTNETLINK answers: File existsDyskretny mechanizm root qdisc jest już skonfigurowanytc qdisc del dev eth0 root pierwsza
Reguły mają zastosowanie, ale ruch nie jest ograniczanyNiewłaściwy interfejs lub TSO/GSO nadal włączoneSprawdź za pomocą ip link show, wyłącz odciążanie za pomocą ethtool -K
Filtr nigdy nie pasujeNieprawidłowa składnia adresu portu/IP lub wyrównanie maskiDodaj działanie przeciwdziałające i sprawdź liczbę trafień w tc -s filter show
Zasady znikają po ponownym uruchomieniuKonfiguracja znajduje się wyłącznie w pamięciZapakuj to w skrypt i wywołaj z systemd lub dyspozytora NetworkManager
Duże opóźnienia w ruchu o wysokim priorytecieBrak qdisc typu „leaf” lub zbyt niski limit burstPrzypisz fq_codel do klas typu „leaf”, zwiększ burst

Jeśli kiedykolwiek zablokujesz sobie dostęp przez błędną konfigurację, reset jest prosty:

tc qdisc del dev eth0 root

tc nie da się wyczarować przepustowości, której nie masz, ale w przypadku dobrze skonfigurowanego łącza uplink stanowi to różnicę między przewidywalną wydajnością a serwerem, który się załamuje w momencie, gdy jeden z użytkowników rozpocznie duży transfer danych. Jeśli potrzebujesz surowej przepustowości i swobody kształtowania jej tak, jak chcesz, zapoznaj się z ofertą serwerów dedykowanych FDC.

Blog

Polecane w tym tygodniu

Więcej artykułów
Samouczek dotyczący programu iperf3: Testowanie prędkości sieci w systemach Linux i Windows
#bandwidth#server-performance

Samouczek dotyczący programu iperf3: Testowanie prędkości sieci w systemach Linux i Windows

Zainstaluj iperf3, przeprowadź testy przepustowości i dostosuj bufory TCP, aby uzyskać dokładne wyniki w systemach Linux i Windows. Obejmuje testy UDP, dwukierunkowe oraz testy 10GbE+.

10 min czytania - 7 maja 2026

#server-performance

Dostosowane profile do optymalizacji obciążenia serwerów z systemem Linux

16 min czytania - 9 czerwca 2026

Więcej artykułów
background image

Masz pytania lub potrzebujesz niestandardowego rozwiązania?

icon

Elastyczne opcje

icon

Globalny zasięg

icon

Natychmiastowe wdrożenie

icon

Elastyczne opcje

icon

Globalny zasięg

icon

Natychmiastowe wdrożenie