后端开发的实用技巧 (1) - 多进程的使用率监控

一、前言

后端业务在线上正常运行的期间, 使用多进程模型的框架在会分离出来固定的进程来承载不同的请求.

这些进程在我们图形化的本地机器上容易实用监控, 如果在远程服务器上应该如何查看进程使用率呢?

二、查找进程PID

我们可以先用ps -aux | grep cfadmin查看到我们的进程PID

root@iZbp18k2vy63cz9njzffe8Z:~# ps aux | grep cfadmin | grep -v grep
root     28383  0.2  0.3  78292  7700 ?        Ssl  Jan11 267:10 ./cfadmin -d
root@iZbp18k2vy63cz9njzffe8Z:~#

三、查看指定进程

通过上述命令的输出, 我们可以看到框架的PID28383, 然后可以使用top -p 28383 -d 0.5来监控这个进程的输出, 并且我们指定了-d参数为每0.5秒刷新一次输出.

top - 15:24:33 up 427 days, 15:43,  2 users,  load average: 0.00, 0.00, 0.00
Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   1914.0 total,    115.7 free,    132.3 used,   1665.9 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   1598.3 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
28383 root      20   0   76.5m   7.5m   4.6m S   0.0   0.4 267:11.55 cfadmin

可以看到结果如我预料的一样, 结果输出效果符合我们的预期.

四、多进程案例

现在我们让框架启动1个主进程和4个工作进程, 这样方便我们演示如何快速查看使用率:

root@iZbp18k2vy63cz9njzffe8Z:~/cfadmin# ./cfadmin -w 4
[2022/04/04 15:27:53] [INFO] httpd listen: 0.0.0.0:8080
[2022/04/04 15:27:53] [INFO] httpd Web Server Running...
[2022/04/04 15:27:53] [INFO] httpd listen: 0.0.0.0:8080
[2022/04/04 15:27:53] [INFO] httpd Web Server Running...
[2022/04/04 15:27:53] [INFO] httpd listen: 0.0.0.0:8080
[2022/04/04 15:27:53] [INFO] httpd Web Server Running...
[2022/04/04 15:27:53] [INFO] httpd listen: 0.0.0.0:8080
[2022/04/04 15:27:53] [INFO] httpd Web Server Running...

这时候我们通过命令行来看过滤进程名字的时候会发现有许多进程PID:

root@iZbp18k2vy63cz9njzffe8Z:~/cfadmin# ps aux | grep cfadmin | grep -v grep
root       705  0.1  0.2   8680  5792 ?        Ssl  15:29   0:00 cfadmin - Manager Process : -w 4 -d
root       706  0.0  0.3  11800  6916 ?        Sl   15:29   0:00 cfadmin - Worker Process
root       707  0.1  0.3  11800  6756 ?        Sl   15:29   0:00 cfadmin - Worker Process
root       708  0.1  0.3  11800  7000 ?        Sl   15:29   0:00 cfadmin - Worker Process
root       709  0.1  0.3  11800  6884 ?        Sl   15:29   0:00 cfadmin - Worker Process
root@iZbp18k2vy63cz9njzffe8Z:~/cfadmin#

我们可以通过使用pidof cfadmin来简化输出, 只获得我们想要的进程PID即可:

root@iZbp18k2vy63cz9njzffe8Z:~# pidof cfadmin
709 708 707 706 705
root@iZbp18k2vy63cz9njzffe8Z:~#

众所周知, top -p 只可以支持通过查看以逗号(,)分隔多个进程PID. 所以我们可以写成这样:

root@iZbp18k2vy63cz9njzffe8Z:~# top -p 709,708,707,706,705
...
top - 15:56:42 up 427 days, 16:15,  3 users,  load average: 0.01, 0.03, 0.00
Tasks:   5 total,   0 running,   5 sleeping,   0 stopped,   0 zombie
%Cpu(s):  1.0 us,  0.7 sy,  0.0 ni, 98.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   1914.0 total,    151.7 free,    141.5 used,   1620.8 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   1589.1 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
  709 root      20   0   11932   6616   4748 S   0.3   0.3   0:02.37 cfadmin
  706 root      20   0   11932   6648   4780 S   0.3   0.3   0:02.31 cfadmin
  708 root      20   0   11932   6732   4864 S   0.0   0.3   0:02.32 cfadmin
  707 root      20   0   11932   6784   4688 S   0.0   0.3   0:02.35 cfadmin
  705 root      20   0    8812   5884   4704 S   0.0   0.3   0:02.30 cfadmin

五、简化复杂度

在前文中我们可以看到多个进程之间还需要来格式化输入进程PID, 这样手动操作起来还是比较麻烦且浪费时间的. 所以, 我们决定通过shell来解决一些效率问题. 例如:

root@iZbp18k2vy63cz9njzffe8Z:~# pidof cfadmin | sed 's/ /,/g'
709,708,707,706,705
root@iZbp18k2vy63cz9njzffe8Z:~#

我们可以使用sed命令将PID输出拼接成我们需要的格式, 然后再使用top -p来完成监控:

root@iZbp18k2vy63cz9njzffe8Z:~# top -p `pidof cfadmin | sed 's/ /,/g'`
...
...
top - 16:18:19 up 427 days, 16:37,  4 users,  load average: 0.05, 0.08, 0.03
Tasks:   5 total,   0 running,   5 sleeping,   0 stopped,   0 zombie
%Cpu(s):  1.1 us,  1.1 sy,  0.0 ni, 97.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   1914.0 total,    149.1 free,    143.5 used,   1621.4 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   1587.1 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM  TIME+ COMMAND
  709 root       20   0    11.7m   6.8m    4.7m S     1.0     0.4     0:04.39  cfadmin
  705 root       20   0     8.6m   5.7m    4.6m S    1.0     0.3     0:04.35  cfadmin
  708 root       20   0    11.7m   6.6m    4.8m S    0.0     0.3     0:04.33  cfadmin
  707 root       20   0    11.7m   6.6m    4.6m S    0.0     0.3     0:04.37  cfadmin
  706 root       20   0    11.7m   6.5m    4.7m S    0.0     0.3     0:04.32  cfadmin

这样每次只需要运行这个命令, 就可以看到所有指定进程与子进程的状态了.