#server-performance

Controlul traficului Linux (tc): un ghid practic

12 min citire - 5 iunie 2026

hero section cover

Controlați lățimea de bandă, prioritizați traficul și modelați traficul de intrare și ieșire pe Linux cu ajutorul comenzii tc. Configurații funcționale pentru HTB, IFB, DSCP și fq_codel pentru servere reale.

Controlul traficului Linux (tc): un ghid practic

Comanda tc vă oferă control direct asupra modului în care serverul dvs. gestionează traficul de rețea. Puteți limita lățimea de bandă pentru fiecare serviciu, puteți menține sesiunile interactive, cum ar fi SSH, receptive atunci când transferurile în bloc ating valori maxime și puteți modela atât fluxurile de ieșire, cât și cele de intrare dintr-un singur instrument. Acest ghid acoperă conceptele de bază, o configurare funcțională a HTB, modelarea traficului de intrare cu IFB, prioritizarea bazată pe DSCP și modul de depanare atunci când apare o problemă.


 

Cum funcționează tc

Fiecare tc configurație este alcătuită din patru componente:

  • qdisc (disciplina de coadă). Programatorul atașat la o interfață de rețea. Acesta decide modul în care pachetele sunt introduse și scoase din coadă.
  • Clasă. O subdiviziune în cadrul unui qdisc bazat pe clase. Gândiți-vă la aceasta ca la o bandă de circulație cu propria limită de viteză.
  • Filtru. Inspectează anteturile pachetelor (adrese IP, porturi, marcaje) și atribuie fiecărui pachet o clasă.
  • Acțiune. Ce se întâmplă cu un pachet odată ce corespunde criteriilor: redirecționare, respingere, redirecționare.

Acestea formează o structură arborescentă. Pachetele intră la qdisc-ul rădăcină, trec prin filtre, sunt sortate în clase de către un major:minor identificator și ajung în coada unui qdisc de nivel inferior pentru a fi transmise.

Pentru orice situație mai complexă decât potrivirea bazată pe port, marcați pachetele cu iptables sau nftables în tabelul mangle, apoi utilizați fw filtrul din tc pentru a clasifica în funcție de marcaj. Se scalează mult mai bine decât lanțurile de reguli brute u32 pentru fiecare tip de trafic.

Ieșire vs intrare

Direcția contează. Kernel-ul poate stoca în buffer și întârzia pachetele de ieșire, ceea ce permite o modelare reală a traficului. Pachetele de intrare au traversat deja rețeaua până în momentul în care le vedeți, așa că le puteți controla doar (respingându-le dacă depășesc un prag) doar dacă le redirecționați mai întâi către un dispozitiv IFB.

CaracteristicăIeșireIntrare
DirecțieIeșireIntrare
ModelareNativNecesită IFB
MonitorizareSuportatSuportat
Utilizare tipicăQoS, partajarea lățimii de bandă, reglarea ritmuluiLimitarea ratei, atenuarea de bază a atacurilor DDoS

Qdisc-urile pe care le veți folosi efectiv

  • HTB (Hierarchical Token Bucket). Cu clase. Utilizați-l atunci când doriți o lățime de bandă minimă garantată pentru fiecare serviciu, cu posibilitatea de a împrumuta capacitatea neutilizată de la alte clase.
  • TBF (Token Bucket Filter). Fără clase. Utilizați-l atunci când trebuie doar să limitați o întreagă interfață la o singură rată.
  • fq_codel (Fair Queuing Controlled Delay). Combină echitatea pe flux cu gestionarea activă a cozilor de așteptare pentru a elimina „bufferbloat”. Este qdisc-ul implicit în majoritatea distribuțiilor Linux încă de la systemd 217 și este livrat implicit pe RHEL 9. Atașați-l întotdeauna ca qdisc de nivel inferior sub clasele HTB; în caz contrar, un singur flux „lacom” poate monopoliza o întreagă clasă.

Configurarea tc pe un server Linux

tc este livrat împreună cu pachetul iproute2. Pe Debian și Ubuntu, instalați-l cu apt-get install iproute2. Pe RHEL și distribuțiile derivate, yum install iproute. Veți avea nevoie de drepturi de root sau de sudo.

Aflați mai întâi numele corect al interfeței. Denumirea greșită a interfeței este cel mai frecvent motiv pentru care o configurație nu produce niciun efect:

ip link show

Verificați ce se află deja pe interfață, inclusiv contoarele în timp real:

tc -s qdisc show dev eth0

Ștergeți orice qdisc de tip „root” existent înainte de a aplica o nouă configurație, pentru a evita RTNETLINK answers: File exists apariția erorilor:

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

Dacă actualizați o regulă existentă în loc să începeți de la zero, utilizați replace în loc de add pentru o schimbare atomică.

Descărcarea hardware, precum TSO și GSO, grupează pachetele într-un mod care interferează cu modelarea. Dezactivați-le pe interfața modelată:

sudo ethtool -K eth0 tso off gso off

Setați fq_codel ca qdisc implicit la nivel de sistem pentru interfețele noi:

sysctl -w net.core.default_qdisc=fq_codel

Pentru serverele foarte solicitate, combinați-l cu algoritmul de control al congestiei BBR (kernel 4.9+). BBR menține un debit ridicat fără a mări cozile:

sysctl -w net.ipv4.tcp_congestion_control=bbr

Un obicei de siguranță dacă configurați un sistem la distanță prin SSH: deschideți o a doua sesiune și aveți tc qdisc del dev eth0 root textul pregătit pentru a fi lipit. O regulă de filtrare greșită vă poate bloca accesul instantaneu.

Modelarea traficului de ieșire cu HTB

HTB vă permite să atribuiți fiecărui serviciu un minim garantat (rate) și o limită maximă (ceil). Lățimea de bandă neutilizată este alocată celor care au nevoie de ea, în ordinea priorităților. Iată o configurație funcțională pe trei niveluri pentru o legătură ascendentă de 1 Gbps.

Creați qdisc-ul HTB rădăcină. Acesta default 30 trimite orice pachet neclasificat către clasa 1:30 în loc să-l lase să ocolească regulile dvs.:

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

Limitați debitul total la 900 Mbps. Reglați întotdeauna debitul puțin sub capacitatea reală a legăturii, altfel se formează o coadă pe un router sau modem din amonte pe care nu îl controlați:

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

Definiți nivelurile de serviciu. Valorile prio primesc în primul rând lățimea de bandă neutilizată:

# 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

Atașați fq_codel ca qdisc de nivel inferior la fiecare clasă, astfel încât un singur flux să nu poată domina nivelul respectiv:

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

Acum clasificați traficul. Pentru potrivirea simplă a porturilor, u32 este cea mai rapidă:

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

Pentru orice operațiune care ține cont de starea sistemului, marcați în iptables și potriviți marca cu 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

Modelarea traficului de intrare cu IFB

Nu puteți modula nativ traficul de intrare, deoarece, în momentul în care un pachet ajunge, acesta a consumat deja lățimea de bandă. Soluția este redirecționarea traficului de intrare către o interfață virtuală de tip Intermediate Functional Block (IFB), unde kernelul îl tratează ca trafic de ieșire și vă permite să aplicați qdisc-uri bazate pe clase.

Încărcați modulul și activați interfața:

modprobe ifb numifbs=1
ip link set dev ifb0 up

Adăugați un qdisc de intrare la interfața fizică și redirecționați totul către 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

De aici, ifb0 se comportă ca orice altă interfață. Aplicați-i arborele HTB exact așa cum ați face-o pentru traficul de ieșire:

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

Prioritizarea traficului cu DSCP

DSCP (Differentiated Services Code Point) etichetează pachetele cu o valoare de 6 biți în octetul TOS, astfel încât tc filtrele să poată clasifica după etichetă, în loc să caute porturile prin setul de reguli. Când se face potrivirea DSCP în tc, deplasați valoarea cu 2 biți spre stânga. DSCP EF (46) devine 0xb8. Masca 0xfc izolează cei 6 biți DSCP de cei 2 biți ECN.

O mapare implicită rezonabilă pentru sarcinile de lucru ale serverelor:

Tipul de traficDSCPTOS hexExemple
InteractivEF0xb8SSH, DNS, VoIP
AfaceriAF410x88HTTP, HTTPS, API-uri
În blocCS10x20Copii de rezervă, FTP, actualizări de pachete
Efort maximCS00x00Orice altceva

Etichetați pachetele de ieșire în iptables înainte ca acestea să ajungă la tc filtrele:

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

Apoi, potriviți eticheta în tc și redirecționați-l către clasa HTB corespunzătoare:

# 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

Monitorizare și depanare

Cele trei comenzi pe care le veți folosi constant:

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

Urmăriți dropped și overlimits . Pachetele pierdute înseamnă că coada este saturată; depășirea limitelor înseamnă că ați atins plafonul clasei și că kernelul a trebuit să întârzie sau să elimine traficul. Pentru o vizualizare în timp real:

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

Adăugați -d pentru parametrii interni (țintă, interval, cuantum) și -j pentru ieșire JSON dacă redirecționați datele către un stack de metrici. Combinați-l cu ss -tin pentru a vedea estimările RTT și retransmisiile la nivelul stratului TCP.

Majoritatea eșecurilor se încadrează într-o listă scurtă:

SimptomCauză probabilăSoluție
RTNETLINK answers: File existsQdisc-ul root este deja configurattc qdisc del dev eth0 root mai întâi
Regulile se aplică, dar traficul nu este limitatInterfață greșită sau TSO/GSO încă activatConfirmați cu ip link show, dezactivați descărcările cu ethtool -K
Filtrul nu se potrivește niciodatăSintaxă incorectă a portului/IP-ului sau aliniere incorectă a măștiiAdăugați o acțiune de contracarare și verificați numărul de accesări în tc -s filter show
Reguli dispărute după repornireConfigurația se află doar în memorieÎncadrați într-un script și apelați din systemd sau dintr-un dispecer NetworkManager
Latență ridicată pentru traficul prioritarNu există qdisc de tip „leaf” sau valoarea de burst este prea micăAtașați fq_codel la clasele „leaf”, creșteți burst

Dacă vreodată rămâneți blocat din cauza unei configurări greșite, resetarea este simplă:

tc qdisc del dev eth0 root

tc nu puteți genera lățime de bandă pe care nu o aveți, dar pe o legătură ascendentă bine aprovizionată aceasta face diferența între o performanță previzibilă și un server care se prăbușește în momentul în care un client începe un transfer de mari dimensiuni. Dacă aveți nevoie de lățimea de bandă brută și de libertatea de a o modela după cum doriți, aruncați o privire la serverele dedicate ale FDC.

Blog

În prim plan săptămâna aceasta

Mai multe articole
Tutorial iperf3: Testați viteza rețelei pe Linux și Windows
#bandwidth#server-performance

Tutorial iperf3: Testați viteza rețelei pe Linux și Windows

Instalați iperf3, efectuați teste de lățime de bandă și reglați bufferele TCP pentru a obține rezultate precise pe Linux și Windows. Acoperă testarea UDP, bidirecțională și 10GbE+.

10 min citire - 7 mai 2026

Mai multe articole
background image

Aveți întrebări sau aveți nevoie de o soluție personalizată?

icon

Opțiuni flexibile

icon

Acoperire globală

icon

Implementare instantanee

icon

Opțiuni flexibile

icon

Acoperire globală

icon

Implementare instantanee