Випадкові тайм‑аути — найгірший тип відмов: надто маленькі, щоб дати чистий стрибок на графіку, надто часті, щоб їх ігнорувати, і
бездоганно вчасні, щоб впасти на того, хто на чергуванні або робить демо. Моніторинг повідомляє «latency elevated», додаток — «upstream timed out»,
а користувачі говорять «не працює» із впевненістю тих, хто ніколи не ганявся за пакетом через три мережі та балансувальник навантаження.
Цей випадок про те, щоб робити нудну, але надійну річ: прослідкуйте шлях за допомогою mtr, зафіксуйте правду з tcpdump
і потім виправте реальну причину — не останню річ, до якої ви торкнулися. Розглянемо Debian/Ubuntu як операційну залу, а мережу — як
пацієнта, який інколи «забуває» згадати, що ще й курить.
Швидкий план діагностики
Коли тайм‑аути «випадкові», реальна закономірність зазвичай схована серед середніх значень. Ваше завдання — примусити систему показати карти.
Ось порядок дій, що знаходить вузькі місця швидко, не витрачаючи день на суперечки з дашбордами.
1) Підтвердіть охоплення за 5 хвилин
- Одна хоста чи багато? Якщо це одна VM — думайте про NIC хоста, драйвер, MTU, локальний брандмауер/conntrack. Якщо цілий шар сервісу — думайте про шлях, LB, DNS, upstream.
- Один напрямок чи багато? Якщо лише один upstream — фокусуйтеся на тому шляху. Якщо багато — підозрюйте стек локальної мережі, резолвер або egress.
- TCP, UDP чи обидва? Якщо лише TCP — часто пахне MSS/MTU, stateful брандмауером, conntrack або бурею ретрансмісій. Якщо лише UDP — в бік DNS, QUIC або ліміти швидкості.
2) Відтворіть з вузла, що тайм‑аутить
- Запустіть аплікаційний прозер (
curlз таймінгами) і пакетний прозер (tcpdump) одночасно. - Зберіть невеликий дамп (30–60 секунд) під час вікна відмови. Не «захоплюйте весь день», якщо не любите пояснювати використання диска.
3) Прослідкуйте шлях за допомогою mtr, але з правильним протоколом
- Користуйтеся
mtr -T(TCP) до реального порту вашого додатку, коли ICMP фільтрується або має нижчий пріоритет. - Порівняйте з двох точок: з вузла, що падає, і з робочого піринга в тому ж підмережі/VPC.
4) Визначте, до якої з цих категорій ви належите
- Втрати на останньому хопі (дестинація): реальна проблема або обмеження швидкості на приймаючій стороні.
- Втрати починаються в середині шляху й тривають: реальні транзитні втрати або конгестивання.
- Втрати лише на одному проміжному хопі: зазвичай це ICMP rate limiting; ігноруйте, якщо латентність/втрати не проявляються далі.
- Немає втрат, але стрибки латентності: bufferbloat, чергування, проблеми з обробкою переривань CPU або ретрансмісії, сховані ICMP.
- Виглядає чисто, але додаток тайм‑аутить: MTU‑чорна діра, асиметрична маршрутизація, conntrack‑скидання або дивна взаємодія DNS/Happy Eyeballs.
5) Зробіть найменшу зміну, яка доводить причинно‑наслідковий зв’язок
- Занижте MSS, відрегулюйте MTU, змініть резолвер, зафіксуйте інтерфейс, змініть пріоритет маршруту або тимчасово вимкніть offload, щоб підтвердити гіпотезу.
- Не виконуйте «мережевий рефакторинг», щоб виправити тайм‑аут. Це не інженерія; це перформанс‑арт.
Практична ментальна модель випадкових тайм‑аутів
Тайм‑аут — це не одиночна відмова. Це фінальний симптом чогось, що займає забагато часу: SYN не отримує відповіді, DNS‑запит застрягає,
запит ретрансмитується, ACK затримується в переповненій черзі, PMTU‑виявлення не завершується або stateful брандмауер мовчки відкидає «дивні» пакети.
Випадкові тайм‑аути зазвичай мають одну з чотирьох форм:
- Мікровтрати з ретрансміями: не помічаєте, доки трафік не зросте або тайм‑аути не стануть коротшими.
- Пакетне чергування: лінк або віртуальний NIC стає перевантаженим, пакети лежать у буферах, латентність стрибає, потім «одужує».
- Непослідовність шляху: ECMP, асиметрична маршрутизація або флапінг маршрутів посилають деякі потоки по «поганій» гілці.
- Протокольне невідповідність: MTU/MSS, баги з checksum/offload або поведінка firewall/conntrack, що проявляється лише при певних розмірах пакетів або швидкостях.
Головне — перестати думати про «мережу» в цілому і почати думати про потоки. Один потік може бути зламаний, а інші виглядати нормально,
особливо коли є балансувальники, NAT або ECMP. Саме тому ви робите захоплення пакетів і шукаєте ретрансмії, сброси та зависання.
Факти й контекст, що роблять вас кращими в цьому
- traceroute старший за більшість SRE‑команд. Його створили в кінці 1980‑х для налагодження маршрутизації та досяжності за допомогою поведінки TTL.
- mtr — це по суті «traceroute з пам’яттю». Воно безперервно вибірково вимірює та показує тренди — ідеально для переривчастих проблем.
- ICMP часто вважають трафіком другого сорту. Багато маршрутизаторів обмежують ICMP‑відповіді, тому mtr на базі ICMP може показувати «втрати», яких насправді немає для TCP.
- PMTUD покладається на ICMP «Fragmentation Needed». Якщо ці ICMP‑повідомлення блокуються, ви можете отримати PMTU‑чорну діру: маленькі пакети працюють, великі зависають.
- TCP‑ретрансмії — нормальна річ, поки ними не зловживають. Кілька ретрансмій трапляються в здорових мережах; стійкі ретрансмії вказують на втрати або сильне перемішування.
- Linux conntrack має обмежені таблиці. Коли таблиці заповнюються, ви не отримуєте пристойної помилки. Ви отримуєте падіння пакетів, які виглядають «випадковими».
- ECMP може зробити налагодження схожим на газлайтинг. Два послідовні проби можуть іти різними шляхами; один шлях може бути нормальним, інший — патологічним.
- Offload‑функції можуть плутати захоплення пакетів. GRO/TSO можуть зробити так, що tcpdump покаже велетенські сегменти, які насправді такою формою ніколи не виходили в ефір, якщо на це не зважати.
- DNS‑тайм‑аути можуть маскуватися під «мережеві тайм‑аути». Ваш додаток може повідомляти про upstream‑тайм‑аути, коли насправді він застряг у пошуку імен.
Практичні завдання: команди, виводи та рішення
Це польові завдання. Кожне містить: виконувану команду, що означає її вивід та яке рішення приймати далі.
Виконуйте їх з хоста, що відчуває тайм‑аути. Якщо можливо, запустіть той самий набір з «відомого робочого» хоста в тій же мережі для порівняння.
Завдання 1: Підтвердіть інтерфейс, IP і маршрут за замовчуванням
cr0x@server:~$ ip -br a
lo UNKNOWN 127.0.0.1/8 ::1/128
ens5 UP 10.20.4.17/24 fe80::5054:ff:fe12:3456/64
cr0x@server:~$ ip route show default
default via 10.20.4.1 dev ens5 proto dhcp src 10.20.4.17 metric 100
Значення: Ви знаєте, який інтерфейс важливий і куди виходить трафік. Якщо у вас кілька маршрутів за замовчуванням — ймовірна причина знайдена.
Рішення: Якщо маршрутизація неоднозначна (декілька default, policy routing), зафіксуйте вибір маршруту за допомогою ip route get (Завдання 2) і шукайте асиметрію маршруту.
Завдання 2: Перевірте вибір маршруту до проблемної дестинації
cr0x@server:~$ ip route get 203.0.113.10
203.0.113.10 via 10.20.4.1 dev ens5 src 10.20.4.17 uid 1000
cache
Значення: Підтверджує egress‑інтерфейс і шлюз для цієї IP.
Рішення: Якщо це змінюється між прогонками — підозрюйте policy routing, кілька таблиць або ECMP на вашому краю. Якщо src IP несподіваний — виправте source‑based routing.
Завдання 3: Перевіріть лічильники лінкового рівня на предмет втрат і помилок
cr0x@server:~$ ip -s link show dev ens5
2: ens5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
RX: bytes packets errors dropped missed mcast
987654321 1234567 0 1423 0 12345
TX: bytes packets errors dropped carrier collsns
876543210 1122334 0 7 0 0
Значення: Втрати на рівні NIC можуть спричиняти ретрансмії та тайм‑аути. Помилки — гірше.
Рішення: Якщо RX‑втрати зростають під час інцидентів — підозрюйте перевантаження хоста, обмеження кільцевих буферів або проблеми віртуального NIC. Перейдіть до Завдання 11 (статистика переривань/softnet) і Завдання 12 (qdisc/черга).
Завдання 4: Швидко перевірте DNS (бо він тихо брешe)
cr0x@server:~$ resolvectl status
Global
Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub
Current DNS Server: 10.20.4.53
DNS Servers: 10.20.4.53 10.20.4.54
cr0x@server:~$ getent ahostsv4 api.example.internal
10.60.8.21 STREAM api.example.internal
10.60.8.21 DGRAM
10.60.8.21 RAW
Значення: Резолвер — systemd‑resolved і у вас два DNS‑сервери. Ім’я резолвиться швидко.
Рішення: Якщо getent зависає або періодично падає — виправте DNS перед тим, як чіпати мережевий шлях. Якщо DNS стабільний — продовжуйте.
Завдання 5: Аплікаційні таймінги з curl (визначте фазу, що зависає)
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://203.0.113.10:443/health
dns:0.000 connect:0.214 tls:0.000 ttfb:2.997 total:3.002
Значення: DNS миттєвий, TCP‑підключення зайняло 214ms, та time‑to‑first‑byte ≈3s. Це не тайм‑аут на з’єднання; це зависання відповіді сервера або подальші втрати після встановлення з’єднання.
Рішення: Захопіть пакети під час цього конкретного запиту (Завдання 9) і запустіть mtr по TCP на порт 443 (Завдання 7).
Завдання 6: mtr з ICMP, щоб отримати першу форму
cr0x@server:~$ mtr -n -r -c 50 203.0.113.10
Start: 2025-12-30T10:14:02+0000
HOST: server Loss% Snt Last Avg Best Wrst StDev
1.|-- 10.20.4.1 0.0% 50 0.3 0.4 0.2 1.8 0.3
2.|-- 10.20.0.1 0.0% 50 0.5 0.6 0.4 2.0 0.3
3.|-- 192.0.2.9 6.0% 50 1.2 1.3 0.9 12.4 1.6
4.|-- 198.51.100.14 0.0% 50 2.1 2.4 1.8 15.6 2.1
5.|-- 203.0.113.10 2.0% 50 2.7 3.1 2.2 48.0 6.7
Значення: Невеликі втрати видно на хопі 3 і на дестинації. Але ICMP‑втрати можуть бути спричинені обмеженням відповіді.
Рішення: Повторіть з mtr по TCP до реального порту (Завдання 7). Якщо TCP показує такі самі втрати/стрибки — вважайте це реальним. Якщо ні — не звинувачуйте хоп 3.
Завдання 7: mtr з TCP SYN на реальний порт служби
cr0x@server:~$ mtr -n -T -P 443 -r -c 50 203.0.113.10
Start: 2025-12-30T10:15:31+0000
HOST: server Loss% Snt Last Avg Best Wrst StDev
1.|-- 10.20.4.1 0.0% 50 0.5 0.6 0.3 3.1 0.6
2.|-- 10.20.0.1 0.0% 50 0.7 0.8 0.5 4.8 0.8
3.|-- 192.0.2.9 0.0% 50 1.4 1.5 1.0 6.5 0.9
4.|-- 198.51.100.14 0.0% 50 2.2 2.6 1.9 21.0 2.9
5.|-- 203.0.113.10 4.0% 50 3.0 6.8 2.4 98.7 17.2
Значення: Тепер втрати видно лише на дестинації, а середня латентність неприємна з поганими піками. Це відповідає реальному болю додатку.
Рішення: Перейдіть від «підозри шляху» до «правди потоку». Захопіть TCP‑ретрансмії й зависання (Завдання 9/10). Також перевірте MTU/PMTUD (Завдання 8).
Завдання 8: Перевірте MTU і поведінку PMTUD (класика чорних дір)
cr0x@server:~$ ip link show dev ens5 | sed -n '1p'
2: ens5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
cr0x@server:~$ ping -M do -s 1472 -c 3 203.0.113.10
PING 203.0.113.10 (203.0.113.10) 1472(1500) bytes of data.
1472 bytes from 203.0.113.10: icmp_seq=1 ttl=54 time=3.11 ms
1472 bytes from 203.0.113.10: icmp_seq=2 ttl=54 time=3.08 ms
1472 bytes from 203.0.113.10: icmp_seq=3 ttl=54 time=3.06 ms
--- 203.0.113.10 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
Значення: Path 1500‑байт працює для ICMP. Це не гарантує, що PMTUD працює для TCP, але добре обнадіює.
Рішення: Якщо це завершується з «Frag needed», зменшіть розмір, поки не пройде, і порівняйте з очікуваним. Якщо запит зависає (немає відповідей), підозрюйте блокування ICMP десь посередині і розгляньте MSS‑клаmpування (розділ Виправлення).
Завдання 9: Захопіть трафік для однієї дестинації (цільовий tcpdump)
cr0x@server:~$ sudo tcpdump -i ens5 -nn -s 0 -w /tmp/case4_443.pcap 'host 203.0.113.10 and tcp port 443'
tcpdump: listening on ens5, link-type EN10MB (Ethernet), snapshot length 262144 bytes
^C
1458 packets captured
1492 packets received by filter
0 packets dropped by kernel
Значення: У вас чисте захоплення з нульовими ядровими втратами. Це важливо: втрати в захопленні змушують звинувачувати мережу за вашу власну проблему з CPU.
Рішення: Якщо tcpdump повідомляє про kernel drops — зменшіть область захоплення, збільшіть буфери або виправте перевантаження хоста (Завдання 11). Потім аналізуйте ретрансмії (Завдання 10).
Завдання 10: Помітити ретрансмії та RST (швидкий метод без tshark)
cr0x@server:~$ sudo tcpdump -nn -tt -r /tmp/case4_443.pcap 'tcp[tcpflags] & (tcp-rst) != 0 or tcp[13] & 0x10 != 0' | head
1735553741.102134 IP 10.20.4.17.51322 > 203.0.113.10.443: Flags [S], seq 240112233, win 64240, options [mss 1460,sackOK,TS val 111 ecr 0,nop,wscale 7], length 0
1735553741.316902 IP 203.0.113.10.443 > 10.20.4.17.51322: Flags [S.], seq 99112233, ack 240112234, win 65535, options [mss 1380,sackOK,TS val 222 ecr 111,nop,wscale 8], length 0
1735553741.317001 IP 10.20.4.17.51322 > 203.0.113.10.443: Flags [.], ack 1, win 502, options [nop,nop,TS val 112 ecr 222], length 0
Значення: Шукаєте шаблони: SYN‑ретрансмії, ретрансмії даних, duplicate ACKs та RST. Фрагмент вище показує нормальний handshake, і сервер рекламує MSS 1380 (цікаво).
Рішення: Якщо бачите повтори SYN без SYN‑ACK — це доступність/фільтрація. Якщо бачите ретрансмії даних і dup ACK шторми — це втрати/чергування. Якщо MSS несподівано низький — дослідіть MTU або оверлей тунелі.
Завдання 11: Перевірте softnet backlog drops (хост може бути вузьким місцем)
cr0x@server:~$ awk '{print "cpu"NR-1, "processed="$1, "dropped="$2, "time_squeeze="$3}' /proc/net/softnet_stat | head
cpu0 processed=12345678 dropped=12 time_squeeze=34
cpu1 processed=12233445 dropped=0 time_squeeze=0
cpu2 processed=11999887 dropped=0 time_squeeze=2
cpu3 processed=12111222 dropped=9 time_squeeze=17
Значення: Drops/time_squeeze вказують, що ядро не встигає обробляти пакети на деяких CPU. Це призводить до «випадкових» втрат з точки зору додатку.
Рішення: Якщо це зростає під час інцидентів — виправляйте хост: IRQ affinity, розміри кільцевих буферів NIC, qdisc або зменшуйте швидкість пакетів. Ще не поспішайте писати тикет «інтернет непевний».
Завдання 12: Перегляньте qdisc і pacing (bufferbloat і чергування)
cr0x@server:~$ tc -s qdisc show dev ens5
qdisc fq_codel 0: root refcnt 2 limit 10240p flows 1024 quantum 1514 target 5.0ms interval 100.0ms ecn
Sent 876543210 bytes 1122334 pkt (dropped 7, overlimits 0 requeues 21)
backlog 0b 0p requeues 21
maxpacket 1514 drop_overlimit 0 new_flow_count 1234 ecn_mark 0
new_flows_len 0 old_flows_len 0
Значення: fq_codel загалом хороший. Невелика кількість дропів — нормально. Overlimits і велика черга підказують про чергування.
Рішення: Якщо бачите масивний backlog/overlimits — ви насичуєте egress або неправильно шейпите. Виправте обмеження пропускної здатності, політики шейпінгу або upstream‑конгестію.
Завдання 13: Перевірте тиск conntrack (stateful‑скидання виглядають як випадкові)
cr0x@server:~$ sudo sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max
net.netfilter.nf_conntrack_count = 24612
net.netfilter.nf_conntrack_max = 262144
cr0x@server:~$ sudo dmesg -T | tail -n 5
[Tue Dec 30 10:12:01 2025] TCP: request_sock_TCP: Possible SYN flooding on port 443. Sending cookies. Check SNMP counters.
[Tue Dec 30 10:12:07 2025] nf_conntrack: table full, dropping packet
Значення: Якщо conntrack повний або близький до повного — пакети відкидаються і з’єднання застопорюються. Ядро тихо каже вам про це в dmesg.
Рішення: Якщо бачите «table full» — збільште розмір conntrack, зменшіть churn з’єднань або припиніть відстежувати потоки, які не потрібні (обережно). Якщо бачите SYN cookies — розслідуйте вхідні шторми або неправильно налаштований backlog.
Завдання 14: Підтвердьте rp_filter і ризик асиметричної маршрутизації
cr0x@server:~$ sysctl net.ipv4.conf.all.rp_filter net.ipv4.conf.ens5.rp_filter
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.ens5.rp_filter = 1
Значення: Строгий reverse path filtering може відкидати легітимний трафік при асиметричній маршрутизації (поширено на multi‑homed хостах, policy routing, деяких cloud‑краях).
Рішення: Якщо ваш шлях асиметричний (підтверджено таблицями маршрутів і захопленнями), поставте rp_filter в loose режим (2) на уражених інтерфейсах, але тільки коли розумієте потенційний вплив.
Використання mtr без самообману
mtr — це ліхтарик, а не стенограма судового засідання. Воно чудово показує, де латентність і втрати здаються присутніми, але може також
штовхнути вас звинуватити невинний хоп, який просто обмежує ICMP‑відповіді. Хитрість — інтерпретувати його як оператор, а не турист.
Три правила для mtr, що запобігають поганим рішенням
-
Втрати на проміжному хопі неважливі, якщо вони не продовжуються далі.
Якщо хоп 3 показує 30% втрат, але хоп 4 і дестинація — 0% втрат, хоп 3, ймовірно, просто не любить ваші проби. -
Підлаштуйте протокол під проблему.
Якщо ваш додаток використовує TCP/443 — використовуйтеmtr -T -P 443. ICMP щось каже, але не завжди те, що вам потрібно. -
Пробуйте довше, щоб зловити «випадковість».
10 проб може виглядати ідеально. 200 проб покажуть 3% втрат, що руйнують хвості латентності.
Жарт №1: Traceroute як офісні плітки — інколи влучний, завжди впевнений і ніколи не розказує, що сталося за дверима кімнати засідань.
Патерни mtr, що мають значення
- Стрибок у латентності: підвищення, що залишається вищим після певного хопу, вказує на повільніший лінк, тунель або перевантажений сегмент.
- Пікові гірші значення на дестинації: проблеми з хвостовою латентністю, часто через черги або переривчасті втрати.
- Втрати лише на дестинації: може бути реальна остання миля, обмеження швидкості на дестинації або поведінка брандмауера на віддаленій стороні. Підтверджуйте tcpdump.
- Чередування поведінки хопів: може вказувати на ECMP, де різні проби йдуть різними шляхами. mtr покаже змішане уявлення.
tcpdump: виявлення ретрансмісій, MTU та зависань
tcpdump — місце, куди відправляються суперечки, щоб померти. Воно не переймається сторінкою статусу вашого провайдера або впевненістю мережевої команди.
Воно показує, що ваш хост відправив, що отримав і чого не отримав назад.
Як захоплювати, не шкодячи пацієнту
- Фільтруйте сильно. Захоплюйте лише хост/порт, що потрібні. Диск і CPU — ресурси продукції.
- Зберігайте короткі інтервали. 30–60 секунд під час поганого вікна краще за 4 години «переважно нормально».
- Фіксуйте ядрові дропи. Якщо tcpdump втрачає пакети — захоплення неповне і висновки сумнівні.
Три TCP‑підписи «випадкових тайм‑аутів»
- SYN‑ретрансмії: спроба підключення не отримує SYN‑ACK. Часто — брандмауер, маршрут або overload upstream.
- Ретрансмії даних і duplicate ACK: втрата пакетів або перемішування. Втрата частіша; перемішування рідше, але небезпечне.
- Зависання після відправлення великих сегментів: MTU/MSS/PMTUD проблеми, особливо якщо малі запити проходять, а великі — зависають.
Випадок №4: шлях виглядає «нормально», поки не стає ненормальним
Цей випадок з’являється в реальних системах, бо сучасні мережі нашаровані: VPC‑оверлей, шифрування, балансувальники навантаження,
NAT‑шлюзи, інколи service mesh. Шлях може бути «доступним», але при цьому неправильним таким чином, що зачіпає лише певні розміри пакетів або потоки.
Симптоми
- Переривчасті тайм‑аути до одного upstream HTTPS API.
- Більшість запитів успішні; деякі зависають на 2–10 секунд, потім падають.
- ICMP ping виглядає чисто. mtr на базі ICMP показує зрідка втрати на середньому хопі, що заводить людей у непродуктивні Slack‑потоки.
- mtr по TCP показує хвостову латентність на дестинації і трохи втрат.
Шлях розслідування, що працює
Почніть з хоста. Доведіть, чи хост відкидає пакети (softnet, NIC‑втрати). Потім доведіть, чи потік ретрансмитується.
Нарешті, перевірте MTU/MSS і наявність тунельних меж.
Ймовірна коренева причина в цьому випадку
Куряча підказка — невідповідність MSS у handshake: сервер рекламує MSS 1380. Це сильно натякає, що десь на шляху
пакети більші за ~1420–1450 байт ризиковані (накладні витрати тунелю, IPsec, GRE/VXLAN або провайдерський край робить щось «цікаве»).
Якщо PMTUD заблокований або ненадійний, деякі потоки зависатимуть, коли спробують надіслати більші TLS‑записи або HTTP‑відповіді.
Часто ви побачите таке поєднання:
- Малі запити (health checks, короткий JSON) проходять.
- Запити, що викликають більші відповіді або завантаження, періодично падають.
- tcpdump показує ретрансмії повноформатних сегментів; відправник відступає, потім зрештою тайм‑аутить.
Доведення за допомогою цільового захоплення
У захопленні шукайте повторювані ретрансмії одного й того ж номера послідовності, особливо коли довжина сегмента близька до вашого MSS.
Також перевіряйте наявність ICMP «fragmentation needed»; якщо їх немає і трафік зависає на більших розмірах — ймовірна PMTUD‑чорна діра.
Жарт №2: баги MTU як блискітки — як тільки вони потрапляють у мережу, з’являються всюди, і ніхто не визнає, хто їх приніс.
Виправлення, які дійсно працюють
Є дві категорії виправлень: «зупинити кровотечу» і «відновити шлях». Розв’язуйте обидві, але в такому порядку.
Системи продукції цінують доступність більше, ніж естетику.
Фікс 1: Clamp TCP MSS на межі (прагматично, часто негайно)
Якщо ви контролюєте брандмауер/роутер/NAT між вашими хостами та upstream, клаmpуйте MSS до безпечного значення, щоб TCP ніколи не намагався
відправляти пакети більші, ніж шлях фактично може перенести. Це обходить залежність від PMTUD.
cr0x@server:~$ sudo iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -o ens5 -j TCPMSS --clamp-mss-to-pmtu
Значення: SYN‑пакети отримують відрегульований MSS відповідно до виявленого PMTU (коли це можливо).
Рішення: Якщо PMTUD зламаний, можливо, потрібно виставити явне значення MSS (наприклад, 1360–1400) залежно від накладних витрат тунелю. Перевірте tcpdump і зменшені тайм‑аути.
Фікс 2: Встановіть правильний MTU на інтерфейсі (вірно, коли ви контролюєте андерлей)
В оверлейних мережах (VXLAN, IPsec) ефективний MTU менший за 1500. Якщо хост думає, що може робити 1500, він це робитиме. А шлях зробить
те, що шляхи роблять: відкине те, що не може перевезти.
cr0x@server:~$ sudo ip link set dev ens5 mtu 1450
Значення: Хост не надсилатиме фрейми більші за 1450 для L3‑payload, відповідно до цього MTU.
Рішення: Робіть це тільки якщо ваше середовище цього очікує (cloud VPCs, тунелі). Підтвердіть, перевіривши рекомендований MTU провайдера і вимірявши ping -M do.
Фікс 3: Припиніть блокувати PMTUD ICMP посеред шляху
Коректне виправлення часто — «дозволити ICMP type 3 code 4» (fragmentation needed) через брандмауери. Але це корпоративні мережі,
тому «коректне» може вимагати зустрічей. Проте: наполягайте на цьому. Це лікує хворобу, а не лише симптом.
cr0x@server:~$ sudo nft list ruleset | sed -n '1,120p'
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iif "lo" accept
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
}
}
Значення: Тут ICMP дозволено (добре). Якщо ви бачите блокування ICMP — PMTUD може не працювати.
Рішення: Дозвольте необхідні ICMP‑повідомлення для вашого середовища. Не «блокуйте весь ICMP», а потім дивуйтеся, чому мережа поводиться дивно.
Фікс 4: Зменшіть падіння пакетів на хості (гігієна softnet/IRQ)
Якщо Завдання 11 показує softnet‑втрати — виправляйте хост. Типові покращення: увімкніть RSS, рознесіть IRQ, не дозволяйте одному CPU тягти всю роботу.
cr0x@server:~$ grep -H . /proc/interrupts | grep -E 'ens5|virtio' | head
/proc/interrupts: 43: 9922331 0 0 0 IR-PCI-MSI 327680-edge virtio0-input.0
/proc/interrupts: 44: 0 8877665 0 0 IR-PCI-MSI 327681-edge virtio0-output.0
Значення: Переривання не збалансовані (CPU0 приймає на себе навантаження на вході).
Рішення: Налаштуйте IRQ affinity або увімкніть irqbalance, якщо підходить, потім знову перевірте softnet під навантаженням.
Фікс 5: Зробіть conntrack нудним знову
Якщо conntrack повний або ви бачите скидки — виправте стан. Збільшувати таблицю варто лише якщо ви розумієте пам’ять і трафік. Краще — зменшити churn:
тримайте з’єднання живими, використовуйте пулінг і не відстежуйте те, що не потрібно (обережно з NAT і політиками безпеки).
cr0x@server:~$ sudo sysctl -w net.netfilter.nf_conntrack_max=524288
net.netfilter.nf_conntrack_max = 524288
Значення: Більше місця для відстежуваних потоків.
Рішення: Якщо лічильник знову підніметься до максимуму — ви не виправили причину, лише дали їй більший склад, щоб палати.
Фікс 6: Віддайте перевагу TCP mtr і probe‑ам на рівні служби в рукбуках
Це культурне виправлення. Оновіть рукбуки так, щоб «прослідкувати шлях» означало «прослідкувати протоколом, що має значення». Це запобігає помилковим звинуваченням і пришвидшує триаж.
Три корпоративні міні‑історії
Міні‑історія 1: Інцидент через хибне припущення
Команда fintech мала набір Ubuntu API‑серверів за керованим балансувальником. Користувачі почали скаржитись на «випадкові збої при оформленні».
На чергуванні запустили ICMP mtr з одного API‑вузла до платіжного шлюзу. Воно показало 20–30% втрат на хопі 4. Висновок утворився миттєво:
«ISP відкидає пакети». Було відкрито тикет. Усі чекали.
Тим часом ретраї привели до купи. Платіжний шлюз побачив сплески трафіку і почав обмежувати швидкість. Тепер тайм‑аути стали гіршими.
Команда додала більше API‑вузлів, що підвищило churn з’єднань і додало тиск на conntrack на egress NAT.
Раптом тайм‑аути перестали бути випадковими — вони стали постійними, і в кожного з’явилась нова улюблена теорія.
Тихіший інженер зробив непопулярну річ: mtr -T -P 443 до шлюзу і 60‑секундний tcpdump під час відмов.
Втрата на хопі 4 зникла при TCP mtr. На дестинації показалися спорадичні SYN‑ретрансмії. tcpdump виявив повторювані SYN без SYN‑ACK під час сплесків.
Справжня причина — stateful брандмауер посередині з агресивними обмеженнями SYN‑рейт, який був скопійований з «загартованого» шаблону.
ICMP‑втрати на хопі 4 були просто ICMP‑депріоритизацією. Хибне припущення — вважати втрати ICMP на проміжному хопі як втрати для вашого додатку.
Фікс був нудний: відрегулювали пороги брандмауера згідно з трафіком, додали повторне використання з’єднань і поставили алерти на SYN‑ретрансмії.
Тикет до ISP закрили з ввічливою відповіддю, як це часто буває.
Міні‑історія 2: Оптимізація, що відплатилася
Медіакомпанія хотіла швидші завантаження на об’єктне сховище. Хтось помітив, що сервери використовують MTU 1500 в датацентрі, де підтримуються jumbo frames.
Пропозиція: поставити MTU 9000 скрізь. Більші фрейми, менше пакетів, менше CPU. Це впровадили на флоті Debian‑боксів.
Пропускна здатність у межах стояків покращилася. Потім почалися скарги: переривчасті тайм‑аути до певних зовнішніх сервісів, нестабільні TLS‑handshake
і дивна поведінка, коли малі API‑виклики проходили, а «важкі» — зависали. mtr виглядав «переважно нормально». Ping працював. Усі ставали самовдоволеними з неправильних причин.
Винуватець передбачуваний: не всі сегменти між серверами й зовнішнім світом підтримували jumbo frames. Деякі шляхи клали, деякі — відкидали,
а ICMP PMTUD‑повідомлення фільтрував проміжний security‑пристрій. Результат: PMTU‑чорні діри для частини потоків.
Оптимізація створила розділену реальність, де той самий хост поводився по‑різному залежно від дестинації.
Відкат був болючий, бо сервіси були підлаштовані під «покращення», і тепер усе довелося переналаштовувати.
Зрештою стандартизували MTU за зонами, задокументували це, дозволили потрібні ICMP для PMTUD і застосували MSS‑клаmpування на кордоні тунелів.
Міні‑історія 3: Нудна, але правильна практика, що врятувала день
SaaS‑платформа мала внутрішнє правило: кожен інцидентний канал мусить містити пакетний дамп з проблемного хоста протягом 20 хвилин.
Люди нарікали, що це бюрократія. Вони хотіли «почати з дашбордів». Дашборди заспокоюють. Пакети — чесні.
Одного дня випадкові тайм‑аути вдарили по набору Ubuntu‑воркерів, що говорили з базою по приватному лінку. Графіки латентності були відносно рівні.
mtr нічого підозрілого не показував. Команда бази наполягала, що нічого не змінювала. Мережна команда теж. Єдина змінна була — звинувачення.
Захоплення показало періодичні сплески ретрансмій, які корелювали з нічним батч‑джобом. На воркерах /proc/net/softnet_stat показав дропи і time_squeeze‑піки
на підмножині CPU під час того батчу.
Проблема не була лінком; проблема була в мережевому стеці хоста, що голодніє під час CPU‑важкої обробки.
Оскільки у них була стандартна практика «знімати дамп рано», вони не витратили день на суперечки про маршрутизатори. Вони зафіксували CPU‑набори для батчу,
налаштували IRQ‑affinity, і тайм‑аути зникли. Ніхто не отримав трофея. Продукція стала тихішою, і це єдиний трофей, який має значення.
Типові помилки: симптом → корінь → фікс
Цей розділ упереджений, бо написаний кров’ю витрачених годин.
1) mtr показує втрати на середньому хопі
Симптоми: mtr повідомляє 10–50% втрат на хопі N, але дестинація виглядає нормально або лише трохи зачеплена.
Корінь: ICMP‑rate limiting або депріоритизація на тому маршрутизаторі. Не реальне форвардинг‑втрачання.
Фікс: Перезапустіть з mtr -T -P <port>. Дійте тільки якщо втрати/латентність продовжуються до дестинації.
2) Випадкові тайм‑аути тільки для «великих» відповідей або завантажень
Симптоми: Health checks проходять. Малі запити проходять. Великі payload‑и зависають або тайм‑аутять.
Корінь: Невідповідний MTU, PMTUD‑чорна діра, наклад тунелю або фільтрований ICMP fragmentation‑needed.
Фікс: Перевірте PMTU з ping -M do, подивіться MSS у SYN/SYN‑ACK, клаmpуйте MSS або встановіть правильний MTU, дозвольте PMTUD ICMP.
3) SYN‑ретрансмії під час піків
Симптоми: tcpdump показує повторювані SYN, мало SYN‑ACK, тайм‑аути під навантаженням.
Корінь: SYN‑rate limiting брандмауера, насичений балансувальник, вичерпаний conntrack/NAT, або тиск на accept backlog upstream.
Фікс: Перевірте conntrack/dmesg, відрегулюйте пороги брандмауера, зменшіть churn з’єднань (keepalive/pooling), масштабуйтесь або налаштуйте upstream.
4) Виглядає як «мережеві втрати», але tcpdump втрачає пакети
Симптоми: tcpdump повідомляє «packets dropped by kernel», softnet‑втрати ростуть, додаток бачить тайм‑аути.
Корінь: Хост не встигає обробляти пакети (CPU‑конкуренція, imbalanced IRQ, шум віртуалізації).
Фікс: Зменшіть область захоплення; виправте хост: IRQ affinity, RSS, irqbalance, CPU pinning, зменшіть швидкість пакетів або перемістіть навантаження.
5) Тайм‑аути лише з однієї підмережі або однієї AZ
Симптоми: Той самий код, той самий сервіс, але одна зона тайм‑аутить частіше.
Корінь: Різний шлях (маршрутизація, NAT‑шлюз, політика брандмауера) або поганий сегмент андерлею.
Фікс: Порівняйте mtr -T і захоплення з кожної зони. Виправте відмінний egress‑шлях; не «надто налаштовуйте додаток», щоб терпіти погану лінію.
6) «Ми ввімкнули strict rp_filter для безпеки» і тепер дивні речі відбуваються
Симптоми: Деякі відповіді ніколи не доходять назад, періодичні дропи на multi‑homed хостах.
Корінь: Асиметрична маршрутизація плюс strict reverse path filtering відкидає легітимні пакети.
Фікс: Використовуйте rp_filter loose режим (2) там, де очікується асиметрія, і документуйте дизайн маршрутів, щоб ніхто не «перезакривував» його пізніше.
Чеклісти / покроковий план
Чекліст A: 30‑хвилинний триаж випадкових тайм‑аутів
- Визначте одну проблемну IP:port і одну робочу контрольну дестинацію.
- Запустіть
curl -wтаймінги (Завдання 5), щоб побачити, чи це connect vs TTFB vs total. - Запустіть
mtr -T -P(Завдання 7) довго, щоб зловити стрибки. - Захопіть 60 секунд з
tcpdump, відфільтроване на той host:port (Завдання 9). - Перевірте NIC‑втрати (Завдання 3) і softnet‑втрати (Завдання 11).
- Перевірте conntrack і dmesg (Завдання 13).
- Швидко протестуйте PMTU за допомогою
ping -M do(Завдання 8). - Зробіть одну зміну для стримування (MSS‑клаmp або налаштування MTU) лише якщо вона чітко відповідає доказам.
Чекліст B: Пакет доказів для мережевої/провайдера
- Часовий мітокований вивід
mtr -T -P, що показує втрати/латентність на дестинації. - Фрагмент pcap із SYN‑ретрансміями або ретрансміями даних (включіть час початку/кінця).
- Source IP, destination IP, порт і чи задіяно NAT.
- Підтвердження, що хост не втрачає пакети (softnet, kernel drops tcpdump).
- Чи MSS/MTU виглядає обмеженим (параметри SYN, спостережувані MSS‑значення).
Чекліст C: Загартування, щоб це не повернулося наступного місяця
- Додайте синтетичні прозери, що вимірюють час підключення і TTFB окремо.
- Алертуйте на TCP‑ретрансмії і SYN‑ретрансмії на вузлі.
- Стандартизуйте MTU по середовищу і документуйте накладні витрати тунелів.
- Залишайте ICMP для PMTUD дозволеним через внутрішні межі.
- Слідкуйте за використанням conntrack там, де є NAT/stateful брандмауери.
- Оновіть рукбуки: за замовчуванням використовуйте TCP mtr до порту служби, а не ICMP.
FAQ
1) Чому ICMP mtr показує втрати, а мій додаток начебто в порядку?
Багато маршрутизаторів обмежують ICMP‑відповіді (control plane), водночас нормально форвардуючи дані (data plane). Використовуйте mtr -T -P, щоб тестувати протокол, який використовує ваш додаток.
2) Чому TCP mtr показує втрати на дестинації — чи може це бути «фейком»?
Менш ймовірно, але дестинації можуть обмежувати SYN/ACK або депріоритизувати відповіді під навантаженням. Підтвердіть tcpdump: чи бачите ви SYN‑ретрансмії або ретрансмії даних?
3) Який найшвидший спосіб виявити MTU‑чорні діри?
Порівняйте поведінку для малих і великих payload‑ів, перевірте MSS у SYN/SYN‑ACK і тестуйте з ping -M do зі збільшенням розмірів. Якщо великі зависають і відсутні ICMP «frag needed», підозрюйте PMTUD‑збій.
4) Чи варто відключати TSO/GRO під час відлагодження?
Тільки якщо ви розумієте чому. Offload‑функції можуть зробити захоплення заплутаними, але відключення в продакшені може погіршити продуктивність. Краще інтерпретувати захоплення з урахуванням offload і тримати тести таргетованими.
5) Мій tcpdump каже «packets dropped by kernel». Мережа винна?
Ні. Це означає, що ваш хост не встигає захоплювати (і часто не встигає обробляти) пакети. Виправте CPU/IRQ/softnet‑проблеми або зменшіть навантаження на захоплення перед тим, як звинувачувати шлях.
6) Як визначити, чи тайм‑аути пов’язані з DNS?
Використайте curl -w, щоб побачити час пошуку імен, і запускайте getent ahosts повторно. DNS‑проблеми проявляються як стрибки в time_namelookup або зависання в викликах резолвера.
7) Чи є MSS‑клаmpування хаком?
Це прагматична стратегія стримування. Правильне довгострокове виправлення — узгоджений MTU і працююча PMTUD, але MSS‑клаmpування широко використовується на межах тунелів, бо воно працює.
8) Як випадкові тайм‑аути стосуються інженерії зберігання?
Віддалене зберігання (iSCSI, NFS, об’єктні шлюзи) швидко перетворює втрати пакетів на зависання додатків. Навіть невелика частка ретрансмій може дати величезну хвостову латентність для синхронного IO.
9) Яку цитату варто пам’ятати під час розслідувань?
«Надія — не стратегія.» — James Cameron
Висновок: наступні кроки
Випадкові тайм‑аути не є випадковими. Вони просто розподілені по потоках, сховані серед середніх значень і захищені улюбленими хибними припущеннями людей.
Надійний робочий процес простий: відтворіть на проблемному хості, прослідкуйте шлях правильним протоколом, захопіть пакети під час відмови
і доведіть, чи маєте ви справу з втратами, чергуванням, MTU/PMTUD або падіннями на рівні хоста.
Наступні кроки, які ви можете зробити сьогодні:
- Оновіть рукбук, щоб за замовчуванням використовувати
mtr -T -Pдля тайм‑аутів додатку. - Додайте легкий tcpdump‑on‑demand процес із жорсткими фільтрами й короткими вікнами захоплення.
- Задокументуйте очікування MTU/MSS у вашому середовищі (особливо якщо є тунелі).
- Інструментуйте ретрансмії та тиск conntrack там, де є NAT/stateful пристрої.
- Коли знайдете фікс — запишіть докази, а не теорію, щоб наступний на чергуванні не переживав вашого вікенду.