Ubuntu 24.04: iperf показує швидкість, а додаток повільний — приховані вузькі місця для перевірки (випадок №24)

Було корисно?

Панель SRE тиха, індикатори лінків радісні, і iperf3 тільки-но «наскричав» “10 Gbit/s”, ніби ним можна пишатися. Тим часом реальний додаток відчувається так, ніби запити відправляють голуби-поштарі. Це той тип відмови, через який команди сваряться в Slack: «Це не може бути мережею, iperf в порядку.» — «Це завжди мережа.» Обидві сторони можуть помилятися.

Випадок №24 — класична пастка: тест пропускної здатності доводить, що труба широка, але вашій робочому навантаженню потрібно інше — низькі хвостові затримки, коректне планування CPU, стабільні черги, передбачуваний DNS або сховище, яке поспішає в ногу. Я покажу, де ховаються вузькі місця в Ubuntu 24.04, як їх ловити командами, які ви реально можете запустити, і як приймати рішення на основі виводу замість збору скріншотів для постмортему.

Швидкий посібник для діагностики

Коли додаток повільний, але iperf3 виглядає чудово, не «тюньте» нічого одразу. Спочатку знайдіть клас вузького місця: CPU/преривання, TCP/шлях, резолюція імен/TLS, сховище або конкуренція на рівні додатка. Ось порядок, який найшвидше знаходить винуватця в продакшені.

1) Підтвердіть, що симптом — затримка, а не просто пропускна здатність

  • Виміряйте час обробки запитів з боку клієнта (логи додатка, таймінги curl, статистика клієнта БД).
  • Запустіть інструмент для вимірювання затримки (ping, mtr, ss retransmits) під час уповільнення.

2) Перевірте навантаження CPU і дисбаланс softirq/irq

  • Якщо CPU забитий, мережа може бути «швидкою» в iperf (один потік на одному ядрі), тоді як реальний додаток блокується на softirq, TLS, GC або системних викликах.
  • Шукайте високі значення softirq, iowait або троттлінг cgroup.

3) Перевірте TCP-здоров’я: ретрансміти, конгестія, MTU‑чорні діри

  • ss -ti показує ретрансміти і pacing.
  • Несумісність MTU та зламаний PMTUD часто дають «швидко іноді» плюс «таємничі зависання».

4) Перевірте черги і дропи: кільця NIC, qdisc, bufferbloat

  • Дропи можуть бути непомітні для iperf, якщо його потоки відновлюються; ваш додаток може не відновлюватись.
  • Слідкуйте за ethtool -S, nstat і статистикою qdisc.

5) Перевірте сховище і файлову систему: iowait, синхронні записи, особливості NFS/SMB

  • Якщо додаток чекає диск, мережеві бенчмарки не мають значення.
  • Дивіться iostat, pidstat -d і опції монтування.

6) Перевірте «комунікаційну» інфраструктуру: DNS, час, TLS, проксі

  • Повільний DNS виглядає як «повільна мережа» і марнує час усіх.
  • Затримки TLS‑рукопотискань можуть домінувати у P99 навіть при ідеальному каналі.

Парафразована ідея (приписують): Вернер Фогельс наполягав, що оптимізують за хвостом, бо користувач бачить найповільнішу частину. Це серцевина цього випадку: iperf каже вам про медіану труби; ваші користувачі застрягли у хвості.

Чому iperf виглядає добре, а додаток страждає

iperf3 — відмінний інструмент. Це також дуже специфічний інструмент: він вимірює пропускну здатність (і трохи втрати/джиттера в UDP режимі) під синтетичним патерном потоків. Справжні додатки зазвичай хочуть іншого набору гарантій:

  • Розподіл затримок, а не просто ширина каналу. Багато додатків посилають малі запити, чекають відповіді, потім відправляють далі. Канал ніколи не буває повністю заповнений. iperf його заповнює.
  • Багато конкурентних потоків. За замовчуванням iperf — один або кілька потоків. Ваш сервіс‑меш може мати тисячі з’єднань.
  • Велика CPU‑витратність на байт. TLS, стиснення, парсинг JSON, логування, копіювання в ядрі, контрольні суми та userspace‑стеки їдять CPU. iperf може бути відносно легким по CPU в порівнянні з цим.
  • Різні кодові шляхи. Ваш додаток може проходити через проксі, NAT, conntrack, DNS, L7 балансувальники, sidecar‑и або VPN. iperf часто запускають точка‑до‑точки і він обходить реальний шлях.
  • Різні розміри пакетів. MSS, MTU, GSO/TSO, GRO/LRO змінюють поведінку. Патерни payload‑ів iperf не дорівнюють вашим.
  • Різний backpressure. Додатки можуть блокуватись на диску, локах, пулах бази даних або rate‑лімітах. Сокет стає посередником, якому всі ставлять провину.

Неприємна правда така: швидкий iperf практично нічого не доводить, окрім «два хости можуть передавати байти, коли їх просять чемно». Продуктивний трафік не завжди просить чемно.

Короткий жарт №1: iperf — як тест на біговій доріжці: він доводить, що ваше серце працює, але не пояснює, чому ви втомлюєтесь несучи пакунки з продуктами.

Цікаві факти та коротка історія, що важать

  • TCP був створений для надійності до того, як швидкість стала модною. Він відмінно перетворює втрати в затримку, коли черги заповнюються.
  • Linux довгі роки використовує розвинені дисципліни чергування. Сучасні налаштування схильні до справедливої черги (наприклад, fq_codel) для боротьби з bufferbloat, але ваше середовище може їх перекривати.
  • «Bufferbloat» став поширеним терміном у опс‑спільноті в 2010‑х. Надто багато буферизації може зробити пропускну здатність гарною, а інтерактивну затримку — жахливою.
  • Модерування переривань і NAPI змінили гру. NIC‑и перейшли від «переривання на пакет» до пакетування, пожертвувавши затримкою заради ефективності CPU — добре, поки це не стає проблемою.
  • TSO/GSO/GRO — це продуктивні чудеса з примітками. Оффлоади зменшують навантаження на CPU, упаковуючи пакети, але можуть приховувати шаблони втрат і ускладнювати діагностику.
  • conntrack не безкоштовний. Становий NAT і трекінг файрволом можуть стати вузьким місцем задовго до насичення каналу.
  • PMTUD‑збої — класичний баг «працює в лабораторії». Якщо ICMP «потрібна фрагментація» блокується, певні шляхи чорніють для великих пакетів і створюють дивні зависання.
  • DNS з „маленької неприємності“ став „серйозною залежністю“. Мікросервіси перетворили запити імен у високочастотне навантаження; таймаути стають видимими для користувача.
  • TLS став швидшим, але й важчим. TLS 1.3 зменшив кількість кругів, але навантажив CPU. На переповнених хостах рукопотискання все ще можуть домінувати.

Практичні завдання: команди, виводи й рішення

Це реальні завдання, які ви можете виконати на Ubuntu 24.04. Кожне містить: команду, що означає вивід, і рішення, яке слід прийняти. Запускайте їх під час уповільнення; інакше ви діагностуєте привида.

Task 1: Reproduce iperf in a way that matches your app

cr0x@server:~$ iperf3 -c 10.0.0.20 -P 8 -t 20
Connecting to host 10.0.0.20, port 5201
[SUM]   0.00-20.00  sec  22.8 GBytes  9.79 Gbits/sec  0             sender
[SUM]   0.00-20.04  sec  22.8 GBytes  9.77 Gbits/sec                  receiver

Що це означає: Кілька паралельних стрімів (-P 8) можуть приховувати обмеження по потоку. Якщо ваш додаток використовує багато з’єднань, це ближче до реальності, ніж один потік.

Рішення: Якщо один потік повільний, а мультипотоковий швидкий, підозрюйте обмеження на потік: алгоритм керування, MTU/PMTUD, поліси чи вузьке місце на одному CPU/IRQ.

Task 2: Measure latency and path stability with mtr

cr0x@server:~$ mtr -rwzc 200 10.0.0.20
Start: 2025-12-30T10:12:31+0000
HOST: server                       Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- 10.0.0.1                    0.0%   200   0.25  0.32  0.19  1.90  0.18
  2.|-- 10.0.0.20                   0.0%   200   0.42  0.55  0.35  5.70  0.44

Що це означає: Низький середній, але високий піковий час вказує на чергування або переривчасті дропи/ретрансміти.

Рішення: Якщо пік корелює з уповільненням додатка, переходьте до перевірки черг/дропів та TCP‑ретрансмітів.

Task 3: See if the host is CPU-starved or stuck in iowait

cr0x@server:~$ uptime
 10:14:02 up 12 days,  3:21,  2 users,  load average: 18.42, 16.90, 14.11

Що це означає: Load average — це runnable + uninterruptible задачі. Високий load може бути через конкуренцію за CPU або очікування I/O.

Рішення: Високий load при низькому використанні CPU часто означає блокування на I/O (диск або мережева файлова система) або конкуренцію за локи. Не торкайтеся налаштувань NIC, доки не з’ясуєте причину.

Task 4: Break down CPU, softirq, and iowait

cr0x@server:~$ mpstat -P ALL 1 5
Linux 6.8.0-xx-generic (server)  12/30/2025  _x86_64_  (32 CPU)

12:14:21     CPU   %usr   %sys  %iowait  %soft  %idle
12:14:22     all   38.10  21.33    0.15   18.40  22.02
12:14:22      7   10.00  15.00    0.00   70.00   5.00

Що це означає: CPU 7 тоне в %soft (softirq). Це обробка пакетів та суміжні роботи.

Рішення: Якщо одне або два ядра зайняті softirq, ймовірний дисбаланс IRQ/RPS/RFS. Виправте це перед тим, як звинувачувати «мережу».

Task 5: Identify which interrupts are hot

cr0x@server:~$ cat /proc/interrupts | egrep -i 'eth0|mlx|ixgbe|enp|eno' | head
  98:  192837465   0   0   0   PCI-MSI 524288-edge      enp5s0f0-TxRx-0
  99:     120044   0   0   0   PCI-MSI 524289-edge      enp5s0f0-TxRx-1
 100:     118900   0   0   0   PCI-MSI 524290-edge      enp5s0f0-TxRx-2

Що це означає: Черга 0 обробляє майже всі переривання. Інші черги бездіяльні.

Рішення: Увімкніть або виправте IRQ‑афініті (або використовуйте irqbalance обережно) і перевірте, чи налаштований RSS і чи рівномірно розподіляє навантаження.

Task 6: Check NIC offloads and current link state

cr0x@server:~$ sudo ethtool enp5s0f0
Settings for enp5s0f0:
	Supported link modes:   1000baseT/Full 10000baseT/Full
	Speed: 10000Mb/s
	Duplex: Full
	Auto-negotiation: on
	Link detected: yes

Що це означає: Лінк домовився на очікуваній швидкості/дуплексі. Якщо ви побачите несподівані 1000Mb/s, зупиніться і виправте кабелі/SFP/конфіг портів комутатора.

Рішення: Виправте фізичний/лінковий шар перед тим, як робити «хитромудрі» програмні налаштування.

Task 7: Look for NIC-level drops and ring overruns

cr0x@server:~$ sudo ethtool -S enp5s0f0 | egrep -i 'drop|discard|miss|overrun|timeout' | head -n 20
rx_missed_errors: 18234
rx_no_buffer_count: 14590
tx_timeout_count: 0

Що це означає: rx_no_buffer_count вказує, що NIC/драйвер вичерпав буфери прийому — часто проблема розміру кілець, starvation CPU/softirq або занадто малих бюджетів пам’яті під навантаженням.

Рішення: Якщо ці лічильники ростуть під час уповільнення, вирішуйте розподіл CPU/IRQ та розгляньте тонування кілець (ethtool -g/-G). Також перевірте, чи нема дефіциту пам’яті на хості.

Task 8: Inspect ring sizes (and whether you can change them)

cr0x@server:~$ sudo ethtool -g enp5s0f0
Ring parameters for enp5s0f0:
Pre-set maximums:
RX:	4096
TX:	4096
Current hardware settings:
RX:	512
TX:	512

Що це означає: Кільця малі відносно максимуму. Малі кільця можуть скидати під мікропавлями; великі кільця можуть підвищувати затримку через надлишкову буферизацію. Обирайте свідомо.

Рішення: Якщо бачите RX‑дропи і спайки затримки під вибуховим навантаженням, помірне збільшення RX‑кільця може допомогти. Якщо ваша проблема — хвостова затримка при помірному навантаженні, не роздувайте буфери бездумно.

Task 9: Check TCP retransmits and socket health

cr0x@server:~$ ss -ti dst 10.0.0.20 | head -n 20
ESTAB 0 0 10.0.0.10:46322 10.0.0.20:443
	 cubic wscale:7,7 rto:204 rtt:3.2/0.8 ato:40 mss:1448 pmtu:1500 rcvmss:1448 advmss:1448
	 bytes_sent:184233 bytes_retrans:12480 bytes_acked:171753 segs_out:2219 segs_in:1962 data_segs_out:2010

Що це означає: Нетривіальний bytes_retrans — палка в руках слідчого. Ретрансміти перетворюються в затримки, head‑of‑line блокування і видиму повільність для користувача.

Рішення: Якщо ретрансміти корелюють з періодами уповільнення, зосередьтеся на втраті на шляху, дропах у чергах, поліcерах, проблемах MTU або помилках драйвера NIC.

Task 10: Check kernel network statistics for retransmits and timeouts

cr0x@server:~$ nstat -az | egrep 'TcpRetransSegs|TcpTimeouts|TcpExtTCPSynRetrans|IpExtInNoRoutes'
TcpRetransSegs             18432              0.0
TcpTimeouts                 1220              0.0
TcpExtTCPSynRetrans          219              0.0

Що це означає: Зростання ретрансмітів/таймаутів вказує на втрати, погане чергування або чорні діри на шляху. SYN‑ретрансміти можуть означати відкидання SYN (фаєрвол, conntrack або перевантажений listener).

Рішення: Якщо SYN‑ретрансміти зростають, перевірте ліміти conntrack, правила файрволу та accept queue/backlog на сервері.

Task 11: Detect MTU/PMTUD blackholes with a controlled probe

cr0x@server:~$ ping -M do -s 1472 -c 5 10.0.0.20
PING 10.0.0.20 (10.0.0.20) 1472(1500) bytes of data.
1472 bytes from 10.0.0.20: icmp_seq=1 ttl=64 time=0.42 ms
1472 bytes from 10.0.0.20: icmp_seq=2 ttl=64 time=0.44 ms

--- 10.0.0.20 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4004ms

Що це означає: Це підтверджує, що MTU 1500 працює end‑to‑end. Якщо воно падає з «Frag needed» або мовчки втрачається, у вас є невідповідність MTU або заблокований ICMP, що викликає PMTUD‑збій.

Рішення: Якщо тест падає, виправте узгодженість MTU або дозволіть необхідні ICMP‑повідомлення. Не «вирішуйте» це випадково MSS‑клаппінгом, якщо ви не контролюєте весь шлях і не розумієте компроміси.

Task 12: Inspect qdisc and queueing behavior

cr0x@server:~$ tc -s qdisc show dev enp5s0f0
qdisc mq 0: root
qdisc fq_codel 0: parent :1 limit 10240p flows 1024 quantum 1514 target 5.0ms interval 100.0ms ecn
 Sent 29837294812 bytes 21833890 pkt (dropped 482, overlimits 0 requeues 1221)
 backlog 0b 0p requeues 1221

Що це означає: Дропи на рівні qdisc можуть бути здоровими (контрольоване скидення) або симптоматичними (занадто малий ліміт, вибухоподібний додаток). Requeues вказують на контенцію або pacing.

Рішення: Якщо бачите стійкі дропи і зростаючу затримку, тонко налаштуйте черги і pacing — але лише після перевірки CPU і дропів NIC. Якщо хвостова затримка — проблема, fq_codel зазвичай ваш друг; заміна його на pfifo_fast — це як подорож у 2009 рік.

Task 13: Check conntrack pressure (NAT/firewall bottleneck)

cr0x@server:~$ sudo sysctl net.netfilter.nf_conntrack_max
net.netfilter.nf_conntrack_max = 262144
cr0x@server:~$ sudo cat /proc/sys/net/netfilter/nf_conntrack_count
258901

Що це означає: Ви близькі до ліміту. Коли conntrack заповнений, нові з’єднання падають або зависають. iperf може і далі працювати, якщо він повторно використовує з’єднання або тестує поза основним шляхом.

Рішення: Збільшіть nf_conntrack_max (з урахуванням пам’яті), зменшіть churn з’єднань або обійдіть conntrack для трафіку, що в ньому не потребує. Також перевірте таймаути, які можуть бути занадто великими для вашого workload.

Task 14: Confirm DNS isn’t the “network problem”

cr0x@server:~$ resolvectl query api.internal.example
api.internal.example: 10.0.0.20                        -- link: enp5s0f0
                     (A) -- flags: answer
                      52ms

Що це означає: 52ms на резолюцію внутрішнього імені підозріло багато для LAN‑контексту. Кілька таких викликів на шлях запиту — і раптом «додаток повільний».

Рішення: Якщо затримка DNS висока або нестабільна, перевірте шлях резолвера (systemd‑resolved, upstream DNS, search‑домен), кешуйте де доречно і виправте upstream.

Task 15: Time a full request: DNS + connect + TLS + first byte

cr0x@server:~$ curl -sS -o /dev/null -w 'dns:%{time_namelookup} connect:%{time_connect} tls:%{time_appconnect} ttfb:%{time_starttransfer} total:%{time_total}\n' https://10.0.0.20/health
dns:0.000 connect:0.003 tls:0.118 ttfb:0.146 total:0.147

Що це означає: TLS‑рукопотискання домінує. «Повільна мережа» насправді може бути CPU‑проблемою, джерелом ентропії, розміром сертифікатного ланцюга, OCSP‑проблемами або перевантаженим TLS‑термінатором.

Рішення: Якщо TLS повільний, профілюйте кінцеву точку термінації: CPU, шифри, відновлення сесій, розмір сертифікатного ланцюга і чи є проксі, що робить додаткову роботу.

Task 16: Check disk I/O wait and saturation (because the app writes somewhere)

cr0x@server:~$ iostat -xz 1 3
Device            r/s     w/s    rkB/s    wkB/s  await  svctm  %util
nvme0n1         120.0   950.0   5200.0  88100.0  24.10   0.70  92.00

Що це означає: Диск ~92% завантажений і середній час очікування 24мс. Додатки, що чекають на диск, «відчувають» мережеву повільність, бо відповіді не генеруються вчасно.

Рішення: Якщо %util високий і await спайкує під час інцидентів, вирішуйте проблему конкуренції за зберігання: розділіть робочі навантаження, тонко налаштуйте fsync, додайте кеш або масштабуйтесь по зберіганню.

Task 17: Find which process is doing the I/O or getting throttled

cr0x@server:~$ pidstat -dl 1 5
# Time   UID   PID  kB_rd/s kB_wr/s  iodelay  Command
10:18:01 1001 21422     0.00  8420.00     120  postgres
10:18:01 0     9981     0.00  1200.00      40  fluent-bit

Що це означає: База даних і агент логування конкурують. В реальному світі логи часто першими з’їдають бюджет затримки.

Рішення: Якщо ваше логування/телеметрія важка, лімітуйте його, виведіть із гарячого шляху або відправляйте на окремий диск. Спостереження, що викликає простій, — це не інженерія, а перформанс‑мистецтво.

Task 18: Check cgroup CPU throttling (common in containers)

cr0x@server:~$ cat /sys/fs/cgroup/system.slice/docker.service/cpu.stat
usage_usec 8922334455
user_usec  6122334400
system_usec 2800000055
nr_periods  238994
nr_throttled 82211
throttled_usec 992233445

Що це означає: Сервіс тротлиться. Це створює спайки затримки, зависання з’єднань і повільний TLS — навіть якщо NIC в порядку.

Рішення: Збільшіть квоту CPU, зменшіть роботу на запит або перерозподіліть розміщення. Якщо ви тротлите, перестаньте трактувати вивід iperf як істину.

Три міні‑історії з бою

Міні‑історія 1: Інцидент через хибні припущення

У них був вікно міграції і чек‑лист. Хтось запустив iperf3 між старими аплікаційними серверами та новим кластером бази даних. Показник досяг лінійної швидкості. Оголосили мережу «валідаваною» і продовжили роботу.

У понеділок черга інцидентів наповнилася «додаток зависає на 10–30 секунд». Не крах. Не жорстка відмова. Просто довгі, принизливі паузи. Нетворкінг‑команда показувала результати iperf. Команда БД показувала графіки CPU, які «в нормі». Команда додатка в паніці переписала три таймаути клієнтів і зробила ще гірше.

Справжня проблема була в невідповідності MTU через VLAN‑межу. Новий шлях мав jumbo frames на частині портів комутатора, а фаєрвол посередині відкидав ICMP «потрібна фрагментація». Малі пакети проходили, тому ping виглядав добре і багато запитів працювали. Певні розміри payload‑ів викликали PMTUD‑фейл і чорні діри, поки TCP не таймаутнув і не спробував менші сегменти.

iperf виглядав добре, бо тест використовував інший шлях (прямий routed hop, що обходив фаєрвол) і бо поведінка стріму відновлювалася. Додаток з безліччю короткоживучих TLS‑з’єднань і випадковими більшими відповідями потрапляв у зламані кейси постійно.

Виправлення було нудне: узгодити MTU, дозволити потрібні типи ICMP для PMTUD і мати один стандартний шлях для тестів. Урок не в тому, що «iperf поганий». Урок — в тому, що припущення «iperf доводить увесь шлях» — брехня, яку ви собі розповіли.

Міні‑історія 2: Оптимізація, що відбилася боком

Платформна команда хотіла знизити завантаження CPU на вузлах Ubuntu 24.04. Мережеву обробку показували у flamegraph як softirq‑час. Хтось запропонував увімкнути більш агресивні оффлоади і збільшити кількість кілець NIC, «щоб ми ніколи не скидали». Звучало розумно. І це вийшло в продакшн у п’ятницю — чудовий індикатор оптимізму.

Використання CPU впало. Успіх, правда? Але симптом, що бачать клієнти — P99 затримка — погіршився. Сильно. Виклики, які зазвичай були стабільні, стали спайковими і непередбачуваними. Бізнес помітив — він завжди помічає, коли ви чіпаєте хвостову затримку.

Проблема була класичним bufferbloat, але всередині хоста. Збільшені кільця і глибші черги поглинали вибухи замість раннього скидання, тому TCP не отримував вчасних сигналів про конгестію. Пакети лежали в буферах довше, і інтерактивні потоки чекали за bulk‑трафіком. Графіки пропускної здатності виглядали відмінно. Користувацький досвід — ні.

Відкат змін одразу покращив P99. Потім зробили по‑дорослому: повторили зміни поступово, міряли хвостову затримку, зберегли справедливе чергування і налаштували кільця лише до межі, де дропи перестали бути патологічними.

Короткий жарт №2: Нічого так не робить систему «швидкою», як буферизація запитів до наступного тижня.

Міні‑історія 3: Нудна, але правильна практика, що врятувала день

Сервіс, що працює поруч з фінансами, мав суворі SLO на затримку і звичку падати під кінець кварталу. Команда не мала часу на героїчне дебагування. Вони зробили нудну річ: стандартизували «золотий» runbook продуктивності для кожного класу хостів.

Кожен вузол відправлявся зі стандартом: узгоджений MTU, відомі налаштування qdisc, шаблони IRQ‑афініті для моделей NIC і невеликий набір «завжди увімкнених» експортерів, що відстежували TcpRetransSegs, CPU softirq і disk await. Вони також зафіксували поведінку DNS: явні резолвери, короткі списки search‑доменів і кешування, де доречно.

Коли впала продуктивність, on‑call не сперечався про ідеологію. Вони порівняли живий хост з базовими виводами. Один вузол показав зростання rx_no_buffer_count і мав іншу версію ядра через пропущений ребут. Ось і все. Ніякого трилера.

Вони злили вузол, перезавантажили до правильної версії ядра, і інцидент закрився. Постмортем був короткий і трохи незручний — найкращий варіант: «ми мали базу, виявили дрейф, виправили дрейф». Практика не була захопливою. Вона була ефективною. Більшість роботи з надійності — це просто запобігання сюрпризам вашому майбутньому я.

Типові помилки: симптом → причина → виправлення

Тут я стаю упередженим. Це патерни, що марнують дні, бо виглядають правдоподібними. Використовуйте як нюх для проблем.

1) «iperf швидкий, отже мережа в порядку»

Симптом: iperf показує високу Gbit/s; додаток має високі P95/P99 затримки і таймаути.

Причина: Ви перевірили пропускну здатність для малої кількості потоків, а не втрати, джиттер, черги чи затримки залежностей. Реальний трафік може йти іншим шляхом (проксі/NAT/VPN/service mesh).

Виправлення: Перезапустіть тести по реальному шляху (той самий VIP, той самий DNS, той самий TLS) і виміряйте ретрансміти, дропи qdisc і таймінги DNS/TLS. Використовуйте розбиття curl -w і ss -ti.

2) «Додаток повільний тільки під навантаженням»

Симптом: Працює при низькому трафіку, колапсує під спайками; iperf в позапіковий час ідеальний.

Причина: Чергування і bufferbloat, softirq‑насичення, виснаження conntrack або конкуренція за диск під реальною конкуруючою роботою.

Виправлення: Спостерігайте під час спайку. Збирайте mpstat, nstat, ethtool -S, tc -s, iostat. Виправляйте найтяжче ресурсне горло: розподіл CPU/IRQ, справедливість qdisc, розміри conntrack або ізоляцію сховища.

3) «Втрат пакетів мізерні, отже це не має значення»

Симптом: Втрата менше 1%, але є видимі для користувача зависання і повтори.

Причина: TCP чутливий до втрат, особливо для коротких потоків і в slow start. Навіть помірні дропи можуть роздути хвостову затримку.

Виправлення: Визначте точку дропів: дропи в кільцях NIC, дропи qdisc, поліси комутатора, Wi‑Fi/underlay проблеми або перенавантажені лінки. Дропи бувають різні; дропи в невдалий момент шкодять більше.

4) «Ми збільшили буфери — тепер стабільно» (поки не стало гірше)

Симптом: Менше дропів, гірша інтерактивність, P99 росте.

Причина: Зайва буферизація викликає затримку в чергах; справедливість між потоками погіршується; TCP бачить конгестію пізніше.

Виправлення: Віддавайте перевагу справедливому чергуванню і контрольованому скидненню над глибокими буферами. Налаштовуйте кільця обережно і міряйте затримку, а не тільки пропускну здатність.

5) «Це Kubernetes/service mesh» (іноді правда, часто лінь)

Симптом: iperf на хості швидкий; pod‑to‑pod або service‑to‑service повільний.

Причина: Невідповідність MTU в оверлеї, тиск conntrack, масштабування kube‑proxy iptables, тротлінг sidecar‑ів або noisy neighbour в cgroup.

Виправлення: Перевірте MTU end‑to‑end, моніторте лічильник conntrack, виміряйте троттлінг CPU по pod‑ах і підтвердіть, що тест використовує той самий сервіс‑шлях, що й продукційний трафік.

6) «БД повільна, але мережа швидка»

Симптом: Запити до БД зависають; iperf в порядку; CPU виглядає нормально.

Причина: Затримка зберігання (fsync, WAL, NFS, насичений NVMe) або конкуренція за локи, що виглядає як «очікування байтів».

Виправлення: Виміряйте iostat await, I/O по процесах з pidstat -d і події очікування специфічно для БД. Не використовуйте мережеві інструменти для діагностики зберігання.

Контрольні списки / поетапний план

Контрольний список A: Коли хтось каже «iperf в порядку»

  1. Запитайте: «Що саме повільно?» Визначте, це час підключення, час TLS, перший байт або загальна відповідь.
  2. Підтвердіть шлях додатка: DNS ім’я, VIP, ланцюжок проксі, NAT, оверлей, зони фаєрволу. Переконайтеся, що ваш тест використовує той самий шлях.
  3. Зніміть ретрансміти і таймаути: ss -ti, nstat.
  4. Зніміть дропи: ethtool -S, tc -s qdisc.
  5. Зніміть softirq і розподіл IRQ: mpstat, /proc/interrupts.
  6. Зніміть затримку сховища: iostat -xz, pidstat -d.
  7. Лише потім думайте про тюнінг. Якщо тюнити спочатку — ви просто змінюєте сцену злочину.

Контрольний список B: Безпечне усунення hotspots IRQ/softirq

  1. Перевірте, чи увімкнений RSS і чи існують множинні черги (ethtool -l, якщо підтримується).
  2. Інспектуйте переривання по черзі в /proc/interrupts.
  3. Перевірте, чи працює irqbalance і чи допомагає або шкодить вашому навантаженню.
  4. Змінюйте по одному параметру (афініті або RPS), потім вимірюйте розподіл softirq і затримку додатка.
  5. Заносьте фінальну конфігурацію в систему керування конфігураціями. Дрейф — мовчазний вбивця.

Контрольний список C: Валідація MTU end‑to‑end

  1. Підтвердіть MTU на інтерфейсах всіх учасників (ip link show).
  2. Протестуйте ping -M do на очікуваний розмір.
  3. Якщо є оверлей/VPN — врахуйте накладення інкапсуляції і зменшіть внутрішній MTU відповідно.
  4. Переконайтеся, що політика безпеки не блокує ICMP, потрібний для PMTUD.
  5. Повторно протестуйте поведінку додатка (TLS рукопотискання, великі відповіді) після змін.

Контрольний список D: Коли пахне DNS

  1. Часуйте запити за допомогою resolvectl query під час інциденту.
  2. Перевірте, чи search‑домени не викликають повторні NXDOMAIN‑запити.
  3. Перевірте upstream резолвери і ефективність кешування.
  4. Підтвердіть, що додаток не робить lookup‑и на кожен запит через відсутність pooling або погану конфігурацію клієнта.

FAQ

1) Якщо iperf швидкий, чи може мережа все ще бути проблемою?

Так. iperf здебільшого доводить пропускну здатність під конкретним патерном потоків. Ваша проблема може бути втратою, джиттері, затримках у чергах, PMTUD, поліcерах або іншому шляху з NAT/проксі.

2) Чи варто запускати iperf з більшою кількістю паралельних потоків?

Зазвичай так. Використовуйте -P, щоб імітувати конкуренцію з’єднань. Якщо багато потоків швидкі, а один повільний — підозрюйте обмеження на потік (втрати, поліси, MTU, алгоритм керування).

3) Який найшвидший індикатор того, що пакети втрачаються?

Зростання ретрансмітів у ss -ti і nstat, плюс лічильники NIC типу rx_no_buffer_count або дропи qdisc у tc -s. Дропи не завжди видно в ping.

4) Чому я бачу високий softirq і додаток сповільнюється?

Softirq — це місце, де ядро обробляє пакети. Якщо він прив’язаний до одного ядра (типово при поганому IRQ/RSS‑розподілі), потоки додатка конкурують за CPU і затримуються. Розподіліть переривання й обробку пакетів по CPU.

5) Чи добре збільшувати NIC ring buffers?

Іноді. Це може зменшити дропи під сплесками, але також може збільшити затримку через більшу буферизацію. Якщо ваш SLO — затримка, налаштовуйте кільця консервативно і міряйте P99 до/після.

6) Як DNS може зробити мою «мережу» повільною?

Кожен lookup — це мережева залежність з таймаутами і повторними спробами. У мікросервісах DNS‑запити часто опиняються на критичному шляху частіше, ніж визнають. Часуйте їх за допомогою resolvectl і розбивайте час запиту через curl -w.

7) Чи може сховище бути вузьким місцем, навіть якщо клієнти скаржаться на «повільні відповіді»?

Абсолютно. Якщо сервер не може швидко читати чи записувати дані, він не зможе швидко відповісти. Перевірте iostat await і %util, потім визначте процеси, що створюють I/O.

8) Чому це відбувається тільки в контейнерах або Kubernetes?

Контейнери додають cgroup‑ліміти, оверлейні мережі і часто шляхи, що навантажені conntrack. Троттлінг CPU, наклад MTU і виснаження conntrack — типові. Вимірюйте троттлінг і лічильники conntrack напряму.

9) Чи варто відключати оффлоади (TSO/GRO/LRO), щоб «виправити затримку»?

Не як перший крок. Відключення оффлоадів часто підвищує використання CPU і може погіршити хвостову затримку під навантаженням. Міняйте оффлоади лише якщо є докази бага драйвера/прошивки або конкретної взаємодії оффлоадів.

10) Що якщо iperf швидкий, ping в порядку, а все одно все зависає?

Дивіться «комунікаційну» інфраструктуру: час TLS‑рукопотискання, DNS, conntrack, черги accept/backlog і виснаження пулів додатка (з’єднання до БД, потоки). Мережеві інструменти не покажуть це безпосередньо.

Висновок: наступні кроки, які можна зробити сьогодні

Якщо ви запам’ятаєте одну річ з випадку №24 — нехай це буде: пропускна здатність ≠ досвід користувача. iperf — грубий інструмент; ваш додаток — примхливий організм, який дбає про хвіст.

Зробіть наступні кроки, у цьому порядку:

  1. Зафіксуйте одне «повільне запитування» з розбиттям (curl -w або таймінги додатка), щоб визначити, чи біль — DNS, connect, TLS чи час сервера.
  2. Під час інциденту зберіть чотири знімки: mpstat, ss -ti, nstat, iostat. Зазвичай цього достатньо, щоб точно вказати підсистему, що бреше.
  3. Якщо гарячі softirq/IRQ — виправте розподіл перед тюнінгом буферів.
  4. Якщо зростають ретрансміти/таймаути — шукайте дропи і MTU‑проблеми end‑to‑end.
  5. Якщо await на сховищі високий — перестаньте звинувачувати мережу і почніть незручну розмову «диск горить».
  6. Запишіть базову конфігурацію і дотримуйтесь її. Найкращий інцидент — той, який ви можете завершити порівнянням виводів, а не імпровізацією.
Наступна →
LGA проти PGA: чому контакти переїхали на материнську плату

Залишити коментар