В данной статье я даю краткий обзор утилит Linux для сбора и анализа статистики важных аспектов работы какого-то определенного Linux-процесса или всей операционной системы в целом. Это, так сказать, быстрый набор «первой помощи», знания о котором пригодится всем разработчикам. Данная статья не пытается охватить все утилиты и все параметры этих утилит. За более подробной информацией вы всегда можете обратиться к страницам man по каждой программе.
ps
Первая утилита, которая дает нам список запущенных процессов.
# ps aux
Используется в сочетании с grep, чтобы найти какой-то определенный процесс по его названию, например, чтобы узнать его PID и местоположение на диске.
Вывод утилиты также показывает параметры командной строки, с которыми был запущен процесс. Это пригодится на тот случай, когда надо удостоверится, что процесс запущен с правильными параметрами, или что параметры записанные в скрипте запуска были правильно переданы приложению при запуске.
vmstat
Выдает статистику по параметрам работы виртуальный машины OS Linux: сколько имеется памяти, сколько свободно, размер свопа, загрузка CPU и т.д.
# vmstat -w procs -----------------------memory---------------------- ---swap-- -----io---- -system-- --------cpu-------- r b swpd free buff cache si so bi bo in cs us sy id wa st 3 0 0 3105128 3300 398264 0 0 196 20 135 83 3 1 94 2 0
mpstat
На многопроцессорной системе показывает нагрузку на каждое ядро каждого процессора (если это многопроцессорная система).
# mpstat -P 0-2
выведет статистику по каждому процессору, где -P — номера процессоров:
Linux 4.18.0-193.6.3.el8_2.x86_64 (apple) 06/28/2020 _x86_64_ (3 CPU) 03:37:17 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 03:37:17 PM 0 1.70 0.02 0.50 0.75 0.29 0.03 0.00 0.00 0.00 96.70 03:37:17 PM 1 1.48 0.03 0.61 1.03 0.34 0.06 0.00 0.00 0.00 96.44 03:37:17 PM 2 1.82 0.02 0.59 0.78 0.31 0.04 0.00 0.00 0.00 96.44
В данном примере у меня под виртуальную машину, в которой крутится Linux, выделено 3 ядра из 4-х имеющихся.
# mpstat -P 0-2 2
будет выводить эту статистику бесконечно каждые 2 секунды
# mpstat -P 0-2 2 5
выведет статистику 5 раз через каждые 2 секунды.
top
Зная PID процесса, можно посмотреть, как работают все его потоки по отдельности:
# top -H -p PID
Так, например, выглядит экран top с информацией о потоках web-приложения, построенного на платформе Spring Boot:
top - 15:13:18 up 3 min, 2 users, load average: 1.23, 1.02, 0.44 Threads: 34 total, 0 running, 34 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.0 us, 0.1 sy, 0.0 ni, 99.9 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st MiB Mem : 3697.2 total, 2868.3 free, 474.8 used, 354.1 buff/cache MiB Swap: 1844.0 total, 1844.0 free, 0.0 used. 2998.4 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1628 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 java 1629 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:06.20 java 1630 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.18 GC Thread#0 1631 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 G1 Main Marker 1632 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.02 G1 Conc#0 1633 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 G1 Refine#0 1634 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 G1 Young RemSet 1636 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.13 VM Thread 1637 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 Reference Handl 1638 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 Finalizer 1639 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 Signal Dispatch 1640 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:02.24 C1 CompilerThre 1641 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.10 Sweeper thread 1642 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 Service Thread 1643 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 VM Periodic Tas 1644 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 Common-Cleaner 1645 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.24 GC Thread#1 1647 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.19 GC Thread#2 1651 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 Catalina-utilit 1652 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 Catalina-utilit 1653 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 container-0 1654 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 http-nio-8888-B 1655 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 http-nio-8888-e 1656 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 http-nio-8888-e 1657 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 http-nio-8888-e 1658 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 http-nio-8888-e 1659 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 http-nio-8888-e 1660 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 http-nio-8888-e 1661 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 http-nio-8888-e 1662 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 http-nio-8888-e 1663 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 http-nio-8888-e 1664 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 http-nio-8888-e 1665 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 http-nio-8888-C 1666 alexk 20 0 4106040 118584 26680 S 0.0 3.1 0:00.00 http-nio-8888-A
Как видно из примера выше, приложение запустило 34 потока! Помимо потоков собственно самого приложения (http) видна также информация о сервисных потоках самой JVM (потоки сборщика мусора и JIT-компилятора) и веб-сервера Tomcat-Catalina. Данный экран поможет в тех случаях, когда надо выяснить, какой из потоков дает основную нагрузку на CPU (колонка %CPU), «жрет» больше всего памяти (колонка %MEM) и нагружает систему ввода-вывода.
Зная PID потока можно с помощью Java-утилиты jstat сделать дамп потоков и выяснить, какой поток в каком именно месте кода ест так много ресурсов.
pidstat
Эта программа — часть пакета утилит sysstat
# yum install sysstat
Использование:
# pidstat -p PID
покажет краткую статистику по выбранному процессу:
Linux 4.18.0-193.6.3.el8_2.x86_64 (kachanov) 07/01/2020 _x86_64_ (3 CPU) 08:00:25 PM UID PID %usr %system %guest %wait %CPU CPU Command 08:00:25 PM 1000 1614 3.85 0.68 0.00 0.00 4.53 2 java
# pidstat -t -p PID
покажет краткую статистику по каждому потоку
Linux 4.18.0-193.6.3.el8_2.x86_64 (kachanov) 07/01/2020 _x86_64_ (3 CPU) 08:02:47 PM UID TGID TID %usr %system %guest %wait %CPU CPU Command 08:02:47 PM 1000 1614 - 2.52 0.46 0.00 0.00 2.98 2 java 08:02:47 PM 1000 - 1614 0.00 0.00 0.00 0.00 0.00 2 |__java 08:02:47 PM 1000 - 1615 1.41 0.28 0.00 0.00 1.68 2 |__java 08:02:47 PM 1000 - 1616 0.05 0.00 0.00 0.00 0.06 0 |__GC Thread#0 08:02:47 PM 1000 - 1617 0.00 0.00 0.00 0.00 0.00 2 |__G1 Main Marker 08:02:47 PM 1000 - 1618 0.00 0.00 0.00 0.00 0.00 2 |__G1 Conc#0 08:02:47 PM 1000 - 1619 0.00 0.00 0.00 0.00 0.00 2 |__G1 Refine#0 08:02:47 PM 1000 - 1620 0.00 0.00 0.00 0.01 0.00 1 |__G1 Young RemSet 08:02:47 PM 1000 - 1621 0.02 0.02 0.00 0.04 0.05 1 |__VM Thread 08:02:47 PM 1000 - 1622 0.00 0.00 0.00 0.02 0.00 2 |__Reference Handl 08:02:47 PM 1000 - 1623 0.00 0.00 0.00 0.00 0.00 2 |__Finalizer 08:02:47 PM 1000 - 1625 0.00 0.00 0.00 0.00 0.00 2 |__Signal Dispatch 08:02:47 PM 1000 - 1626 0.63 0.08 0.00 0.02 0.71 0 |__C1 CompilerThre 08:02:47 PM 1000 - 1627 0.01 0.00 0.00 0.03 0.01 2 |__Sweeper thread 08:02:47 PM 1000 - 1628 0.00 0.00 0.00 0.00 0.00 2 |__Service Thread 08:02:47 PM 1000 - 1629 0.02 0.01 0.00 0.14 0.03 1 |__VM Periodic Tas 08:02:47 PM 1000 - 1630 0.00 0.00 0.00 0.00 0.00 1 |__Common-Cleaner 08:02:47 PM 1000 - 1631 0.04 0.00 0.00 0.01 0.04 2 |__GC Thread#1 08:02:47 PM 1000 - 1633 0.04 0.00 0.00 0.00 0.04 0 |__GC Thread#2 08:02:47 PM 1000 - 1637 0.01 0.00 0.00 0.00 0.01 1 |__Catalina-utilit 08:02:47 PM 1000 - 1638 0.00 0.00 0.00 0.00 0.01 1 |__Catalina-utilit 08:02:47 PM 1000 - 1639 0.00 0.00 0.00 0.00 0.00 1 |__container-0 08:02:47 PM 1000 - 1640 0.00 0.00 0.00 0.00 0.00 0 |__http-nio-8888-B 08:02:47 PM 1000 - 1641 0.00 0.00 0.00 0.00 0.00 1 |__http-nio-8888-e 08:02:47 PM 1000 - 1642 0.00 0.00 0.00 0.00 0.00 0 |__http-nio-8888-e 08:02:47 PM 1000 - 1643 0.00 0.00 0.00 0.00 0.00 1 |__http-nio-8888-e 08:02:47 PM 1000 - 1644 0.00 0.00 0.00 0.00 0.00 0 |__http-nio-8888-e 08:02:47 PM 1000 - 1645 0.00 0.00 0.00 0.00 0.00 1 |__http-nio-8888-e 08:02:47 PM 1000 - 1646 0.00 0.00 0.00 0.00 0.00 0 |__http-nio-8888-e 08:02:47 PM 1000 - 1647 0.00 0.00 0.00 0.00 0.00 1 |__http-nio-8888-e 08:02:47 PM 1000 - 1648 0.00 0.00 0.00 0.00 0.00 0 |__http-nio-8888-e 08:02:47 PM 1000 - 1649 0.00 0.00 0.00 0.00 0.00 1 |__http-nio-8888-e 08:02:47 PM 1000 - 1650 0.00 0.00 0.00 0.00 0.00 0 |__http-nio-8888-e 08:02:47 PM 1000 - 1651 0.00 0.00 0.00 0.00 0.00 1 |__http-nio-8888-C 08:02:47 PM 1000 - 1652 0.00 0.00 0.00 0.00 0.00 0 |__http-nio-8888-A
Идентификатор TID поможет найти поток в дампе потоков, сделанном с помощью jstat.
# pidstat -w -p PID
покажет статистику переключения контекстов для всего приложения в целом:
Linux 4.18.0-193.6.3.el8_2.x86_64 (kachanov) 07/01/2020 _x86_64_ (3 CPU) 08:01:11 PM UID PID cswch/s nvcswch/s Command 08:01:11 PM 1000 1614 0.01 0.00 java
# pidstat -w -t -p PID
покажет статистику переключения контекстов по каждому потоку данного процесса:
Linux 4.18.0-193.6.3.el8_2.x86_64 (kachanov) 07/01/2020 _x86_64_ (3 CPU) 08:01:59 PM UID TGID TID cswch/s nvcswch/s Command 08:01:59 PM 1000 1614 - 0.01 0.00 java 08:01:59 PM 1000 - 1614 0.01 0.00 |__java 08:01:59 PM 1000 - 1615 3.62 0.13 |__java 08:01:59 PM 1000 - 1616 0.98 0.02 |__GC Thread#0 08:01:59 PM 1000 - 1617 0.03 0.00 |__G1 Main Marker 08:01:59 PM 1000 - 1618 0.03 0.00 |__G1 Conc#0 08:01:59 PM 1000 - 1619 0.01 0.00 |__G1 Refine#0 08:01:59 PM 1000 - 1620 2.01 0.00 |__G1 Young RemSet 08:01:59 PM 1000 - 1621 3.26 0.00 |__VM Thread 08:01:59 PM 1000 - 1622 0.06 0.00 |__Reference Handl 08:01:59 PM 1000 - 1623 0.01 0.00 |__Finalizer 08:01:59 PM 1000 - 1625 0.01 0.00 |__Signal Dispatch 08:01:59 PM 1000 - 1626 2.63 0.15 |__C1 CompilerThre 08:01:59 PM 1000 - 1627 0.51 0.00 |__Sweeper thread 08:01:59 PM 1000 - 1628 0.10 0.00 |__Service Thread 08:01:59 PM 1000 - 1629 11.52 0.00 |__VM Periodic Tas 08:01:59 PM 1000 - 1630 0.19 0.00 |__Common-Cleaner 08:01:59 PM 1000 - 1631 0.90 0.03 |__GC Thread#1 08:01:59 PM 1000 - 1633 0.42 0.01 |__GC Thread#2 08:01:59 PM 1000 - 1637 0.77 0.00 |__Catalina-utilit 08:01:59 PM 1000 - 1638 0.75 0.00 |__Catalina-utilit 08:01:59 PM 1000 - 1639 0.06 0.00 |__container-0 08:01:59 PM 1000 - 1640 0.58 0.00 |__http-nio-8888-B 08:01:59 PM 1000 - 1641 0.01 0.00 |__http-nio-8888-e 08:01:59 PM 1000 - 1642 0.01 0.00 |__http-nio-8888-e 08:01:59 PM 1000 - 1643 0.01 0.00 |__http-nio-8888-e 08:01:59 PM 1000 - 1644 0.01 0.00 |__http-nio-8888-e 08:01:59 PM 1000 - 1645 0.01 0.00 |__http-nio-8888-e 08:01:59 PM 1000 - 1646 0.01 0.00 |__http-nio-8888-e 08:01:59 PM 1000 - 1647 0.01 0.00 |__http-nio-8888-e 08:01:59 PM 1000 - 1648 0.01 0.00 |__http-nio-8888-e 08:01:59 PM 1000 - 1649 0.01 0.00 |__http-nio-8888-e 08:01:59 PM 1000 - 1650 0.01 0.00 |__http-nio-8888-e 08:01:59 PM 1000 - 1651 0.57 0.00 |__http-nio-8888-C 08:01:59 PM 1000 - 1652 0.01 0.00 |__http-nio-8888-A
iostat
Утилита показывает статистику по нагрузке на систему ввода вывода:
# iostat Linux 4.18.0-193.6.3.el8_2.x86_64 (kachanov) 06/26/2020 _x86_64_ (3 CPU) avg-cpu: %user %nice %system %iowait %steal %idle 2.33 0.22 1.06 1.21 0.00 95.18 Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn sda 12.71 415.58 82.80 360608 71848 scd0 0.02 0.08 0.00 72 0 dm-0 12.43 368.83 83.78 320039 72696 dm-1 0.11 2.56 0.00 2220 0
pmap
Показывает карту процесса. Утилите передается в качестве параметра PID процесса, который надо исследовать, например, посмотреть какие библиотеки системные подгружены к вашему приложению:
# pmap 1548 1548: -bash 000055b01cdc9000 1056K r-x-- bash 000055b01d0d0000 16K r---- bash 000055b01d0d4000 36K rw--- bash 000055b01d0dd000 40K rw--- [ anon ] 000055b01e552000 396K rw--- [ anon ] 00007fc0d05c6000 2528K r---- LC_COLLATE 00007fc0d083e000 8212K r--s- passwd 00007fc0d1043000 32K r-x-- libnss_sss.so.2 00007fc0d104b000 2044K ----- libnss_sss.so.2 00007fc0d124a000 4K r---- libnss_sss.so.2 00007fc0d124b000 4K rw--- libnss_sss.so.2 00007fc0d124c000 1764K r-x-- libc-2.28.so 00007fc0d1405000 2044K ----- libc-2.28.so 00007fc0d1604000 16K r---- libc-2.28.so 00007fc0d1608000 8K rw--- libc-2.28.so 00007fc0d160a000 16K rw--- [ anon ] 00007fc0d160e000 12K r-x-- libdl-2.28.so 00007fc0d1611000 2044K ----- libdl-2.28.so 00007fc0d1810000 4K r---- libdl-2.28.so 00007fc0d1811000 4K rw--- libdl-2.28.so 00007fc0d1812000 164K r-x-- libtinfo.so.6.1 00007fc0d183b000 2044K ----- libtinfo.so.6.1 00007fc0d1a3a000 16K r---- libtinfo.so.6.1 00007fc0d1a3e000 4K rw--- libtinfo.so.6.1 00007fc0d1a3f000 164K r-x-- ld-2.28.so 00007fc0d1bfe000 332K r---- LC_CTYPE 00007fc0d1c51000 4K r---- LC_NUMERIC 00007fc0d1c52000 4K r---- LC_TIME 00007fc0d1c53000 4K r---- LC_MONETARY 00007fc0d1c54000 4K r---- SYS_LC_MESSAGES 00007fc0d1c55000 28K r--s- gconv-modules.cache 00007fc0d1c5c000 20K rw--- [ anon ] 00007fc0d1c61000 4K r---- LC_PAPER 00007fc0d1c62000 4K r---- LC_NAME 00007fc0d1c63000 4K r---- LC_ADDRESS 00007fc0d1c64000 4K r---- LC_TELEPHONE 00007fc0d1c65000 4K r---- LC_MEASUREMENT 00007fc0d1c66000 4K r---- LC_IDENTIFICATION 00007fc0d1c67000 4K r---- ld-2.28.so 00007fc0d1c68000 4K rw--- ld-2.28.so 00007fc0d1c69000 4K rw--- [ anon ] 00007fffaed87000 132K rw--- [ stack ] 00007fffaedbb000 12K r---- [ anon ] 00007fffaedbe000 8K r-x-- [ anon ] ffffffffff600000 4K r-x-- [ anon ]
numactl
Устанавливается командой:
# yum install numactl
Использование:
# numactl -H available: 1 nodes (0) node 0 cpus: 0 1 2 node 0 size: 3696 MB node 0 free: 3058 MB node distances: node 0 0: 10
Или:
# numactl -s policy: default preferred node: current physcpubind: 0 1 2 cpubind: 0 nodebind: 0 membind: 0
netstat
Входит в пакет утилит net-tools:
# yum install net-tools
Использование:
# netstat -nap
покажет какой процесс какие порты открыл, если надо проверить, скажем, какой процесс занял порт, который требуется вашему приложению.
# netstat -s
lscpu
Утилита выдаст инвентарную информацию о системе: количество процессоров (ядер), их типы (Family, model, vendor) и характеристики (размеры кэшей, наличие/отсутствие определенных технологий):
# lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 3 On-line CPU(s) list: 0-2 Thread(s) per core: 1 Core(s) per socket: 3 Socket(s): 1 NUMA node(s): 1 Vendor ID: GenuineIntel CPU family: 6 Model: 94 Model name: Intel(R) Core(TM) i5-6400T CPU @ 2.20GHz Stepping: 3 CPU MHz: 2208.002 BogoMIPS: 4416.00 Virtualization: VT-x Hypervisor vendor: KVM Virtualization type: full L1d cache: 32K L1i cache: 32K L2 cache: 256K L3 cache: 6144K NUMA node0 CPU(s): 0-2 Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc cpuid tsc_known_freq pni pclmulqdq vmx ssse3 cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single pti tpr_shadow flexpriority fsgsbase avx2 invpcid rdseed clflushopt flush_l1d
lspci
Устанавливается с пакетом pciutils:
# yum install pciutils
Утилита выдает список PIC-портов и их характеристики:
# lspci 00:00.0 Host bridge: Intel Corporation 440FX - 82441FX PMC [Natoma] (rev 02) 00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II] 00:01.1 IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01) 00:02.0 VGA compatible controller: VMware SVGA II Adapter 00:03.0 Ethernet controller: Intel Corporation 82540EM Gigabit Ethernet Controller (rev 02) 00:04.0 System peripheral: InnoTek Systemberatung GmbH VirtualBox Guest Service 00:05.0 Multimedia audio controller: Intel Corporation 82801AA AC'97 Audio Controller (rev 01) 00:06.0 USB controller: Apple Inc. KeyLargo/Intrepid USB 00:07.0 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 08) 00:0d.0 SATA controller: Intel Corporation 82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (rev 02)
Выводы
Данный список далеко не исчерпывающий. Открытость операционной системы позволяет даже писать свои личные утилиты. И таковых уже создано великое множество. Благодаря им можнос подробно исследовать все аспекты работы вашей программной системы и отыскать, где спрятаны «узкие места», где происходит чрезмерная загрузка какой-то подсистемы:
Очень рекомендую вам обратить внимание на сборник утилит eBPF, который развивает инженер-программист компании Netflix Брендан Грегг. Пакет eBPF это попытка оснастить Linux такой же мощной системой мониторинга и трейсинга, которая есть у OS Solaris — DTrace. На сайте Брендана представлено много полезных статей о замерах прощизводительности Linux, а также ссылки на его книги.
- Утилиты для мониторинга JVM позволяют глубже исследовать Java-программу на предмет производительности.