ss -tnp показывает все соединения вместе с процессами, которые их держат, а ss -ti добавляет счётчики байтов по каждому сокету. Вместе это даёт трафик в привязке к процессу без установки чего бы то ни было — а это важно на чужом сервере, внутри контейнера и везде, где нет root, чтобы доставить пакет.
1. Кто подключён и чей это процесс
$ clai покажи установленные соединения вместе с процессами→ ss -tnp 'sport = :8099 or dport = :8099'State Recv-Q Send-Q Local Address:Port Peer Address:Port Process ESTAB 0 4190912 127.0.0.1:8099 127.0.0.1:52080 users:(("python3",pid=1120102,fd=4))ESTAB 324447 0 127.0.0.1:52080 127.0.0.1:8099 users:(("curl",pid=1120130,fd=4))
Колонка Process сразу даёт имя и pid. Send-Q в четыре мегабайта на отдающей стороне — это данные, которые приложение уже записало, а сеть ещё не забрала: надёжный признак, что именно этот сокет и забивает канал.
2. Сколько байт прошло через один сокет
$ clai покажи, сколько байт передано по этому соединению→ ss -tin 'dport = :8099' | grep -oE 'bytes_sent:[0-9]+|bytes_received:[0-9]+'bytes_sent:85bytes_received:8579963
Вот ради чего всё это. -i добавляет внутреннюю статистику TCP, а в ней есть счётчики байтов по сокету. Это и есть «трафик по процессам» без nethogs: предыдущая команда уже связала сокет с pid.
3. Общие счётчики интерфейса
$ clai покажи счётчики трафика интерфейса lo→ grep -E '^\s*lo:' /proc/net/dev | awk '{print "rx_bytes="$2, "tx_bytes="$10}'rx_bytes=581097986 tx_bytes=581097986
/proc/net/dev есть в любой системе Linux, включая контейнеры. Это счётчики с момента загрузки, поэтому сами по себе они ничего не значат — смысл появляется в разнице между двумя замерами.
4. Скорость за одну секунду
$ clai посчитай скорость передачи на lo за одну секунду→ a=$(awk '/^ *lo:/{print $10}' /proc/net/dev); sleep 1; b=$(awk '/^ *lo:/{print $10}' /proc/net/dev); echo "$(( (b-a)/1024 )) KB/s"4764 KB/s
Два замера с паузой в секунду — весь принцип, на котором работает любой измеритель скорости. Замените lo на eth0 или enp5s0.
5. Топ процессов по числу соединений
$ clai покажи, у каких процессов больше всего соединений→ ss -tnp | awk 'NR>1 {match($0,/"[^"]+"/); if (RSTART) print substr($0,RSTART+1,RLENGTH-2)}' | sort | uniq -c | sort -rn | head -5
Число соединений — это не трафик, но хороший первый срез: процесс с сотней сокетов виден сразу. Дальше по подозреваемому смотрим счётчики байтов из шага 2.
6. Наблюдать в динамике
$ clai обновляй список соединений каждую секунду→ watch -n1 "ss -tnp state established"
У ss нет собственного режима повтора, его выдаёт watch. Это бедный родственник iftop, зато доступный на любой машине, куда вы когда-либо зайдёте.
Gotchas
- Число соединений — не пропускная способность. Один сокет может тянуть гигабайты, а сотня простаивающих keep-alive соединений не двигает ничего. Соединения помогают найти подозреваемого, счётчики из
ss -ti— это доказательство. - Без root видны только свои процессы. Колонка Process заполняется для чужих сокетов только под
sudo. Пустое поле рядом с чужим соединением означает «не ваш процесс», а не «процесса нет». - Счётчики интерфейса включают всё, что происходит на машине. В
/proc/net/devпопадают и обновления пакетов, и агенты мониторинга, и соседние контейнеры. За точным ответом идите к сокету, а не к интерфейсу.
Related questions
Когда nethogs всё-таки стоит поставить? Когда нужен постоянный и удобный мониторинг по процессам. Разовую диагностику ss закрывает полностью, а вот часами смотреть в него неудобно.
Как увидеть трафик контейнера? Его счётчики живут в собственном сетевом пространстве имён: docker exec <имя> cat /proc/net/dev покажет трафик ровно этого контейнера.
Как отличить забитый канал от медленного приложения? Растущая Send-Q при неизменной скорости означает, что приложение пишет быстрее, чем сеть успевает забирать. Пустая Send-Q при низкой скорости указывает на приложение или на удалённую сторону.
See also
- netstat: command not found — пользуйтесь ss
- Измерить задержку API через curl
- Проверить, открыт ли порт
CliAI собирает эти фильтры ss из обычной фразы, чтобы не держать синтаксис в голове. Поставить одной строкой.