进程监控,有效的黑盒监控手段
随着技术的进步以及研发人员意识提升,越来越多的进程已经内置暴露了健康检查的接口以及监控指标的接口,比如 Prometheus 生态的 /metrics
接口。但是,有一些进程并没有暴露这些接口,尤其是跑在宿主机上的一些进程,此时就需要一些黑盒监控手段了,比如本文要介绍的进程监控。
进程监控的目标
进程监控主要是监控进程的存活性以及进程的资源消耗情况。有很多 agent 都可以采集这些信息,在夜莺社区里,我们推荐使用 Categraf 进行进程监控。Categraf 包含近百种采集插件,其中就包含了 procstat 插件,用于进程监控。本文以 Categraf 为例,介绍如何使用 Categraf 进行进程监控。其他 agent 也是类似的原理。
进程监控的原理
以 Linux 为例,操作系统的 /proc
目录下存放了所有进程的信息,以进程 pid 作为目录名,下面包括进程的 name、cmdline、环境变量、limits、io 等各类信息,procstat
插件其实就是读取这些信息来监控进程的。
比如我知道某个机器部署了 n9e-foo
进程,想监控这个进程的存活性,其实就是遍历 /proc
下所有的进程,统计有几个进程其名字是 n9e-foo
,如果有 0 个,那就说明进程挂了。从哪里读取进程名字?其实是从 /proc/pid/status
文件里读取的,比如我的环境里有个进程其 pid 是 4481,我们可以看一下这个进程的 status 文件:
root@ubuntu-linux-22-04-desktop:/proc/4481# head /proc/4481/status
Name: node_exporter
Umask: 0022
State: S (sleeping)
Tgid: 4481
Ngid: 0
Pid: 4481
PPid: 4296
TracerPid: 0
Uid: 0 0 0 0
Gid: 0 0 0 0
从第一行可以看到,这个进程的名字是 node_exporter
。
当然了,有些进程其名字不具备很好的区分度,比如所有的 Java 进程,不管是 Kafka 还是 Tomcat,其进程名字都是 java
,这时候就需要结合 cmdline 信息来区分了。
下面我给大家找一个 Java 的进程,看看其 cmdline 信息:
[root@iZ2ze4oi71k3qgdxwsyn07Z ~]# cat /proc/1272973/cmdline | tr '\0' ' '
/usr/bin/java -server -Dlogback.configurationFile=/etc/zabbix/zabbix_java_gateway_logback.xml -classpath lib:lib/android-json-4.3_r3.1.jar:lib/logback-classic-1.2.9.jar:lib/logback-core-1.2.9.jar:lib/slf4j-api-1.7.32.jar:bin/zabbix-java-gateway-7.0.6.jar -Dsun.rmi.transport.tcp.responseTimeout=3000 com.zabbix.gateway.JavaGateway
如果直接 cat cmdline 文件,会发现是一串没有分隔的字符串,这是因为 cmdline 文件是以 \0
分隔的,而 \0
是一个不可见字符,所以我们需要用 tr
命令把 \0
替换成空格,这样就可以较为清晰地看到进程的启动命令了。
可以通过 name、cmdline 等信息过滤进程了,自然就可以统计进程的数量,也可以通过读取进程目录下的其他文件统计进程的资源消耗情况。下面我们来看看如何配置 Categraf 来监控进程。
Categraf 进程监控配置样例
机器上进程很多,我们要做进程监控,就要想办法告诉 Categraf 要监控哪些进程,通过 search 打头的那几个配置,可以做进程过滤筛选:
# 这是要监控的第一个进程
# [[instances]] 这一行默认是注释的,需要打开注释
[[instances]]
# # executable name (ie, pgrep <search_exec_substring>)
search_exec_substring = "nginx"
# # pattern as argument for pgrep (ie, pgrep -f <search_cmdline_substring>)
# search_cmdline_substring = "n9e server"
# # windows service name
# search_win_service = ""
gather_total = true
gather_per_pid = false
gather_more_metrics = [
"threads",
"fd",
"io",
"uptime",
"cpu",
"mem",
"limit",
]
# 这是要监控的第二个进程
[[instances]]
search_cmdline_substring = "kafka"
gather_total = true
gather_per_pid = false
gather_more_metrics = [
"threads",
"fd",
"io",
"uptime",
"cpu",
"mem",
"limit",
"jvm",
]
- search_exec_substring 相当于拿
readlink -e /proc/<pid>/exe
与 search_exec_substring 的内容做字符串匹配,如果匹配上了,就采集这个进程的信息 - search_cmdline_substring 相当于拿
cat /proc/<pid>/cmdline
与 search_cmdline_substring 的内容做字符串匹配,如果匹配上了,就采集这个进程的信息 - search_win_service 用于 windows 机器,表示要监控的 windows 服务名字, 当然 windows 机器上也可以用 search_exec_substring 或者 search_cmdline_substring 来做进程筛选
上面三个 search 相关的配置,每个 [[instances]]
配置段选用其中一个。有一个额外的配置,search_user 配合search_exec_substring 或者 search_cmdline_substring 使用,表示匹配指定 username 的特定进程。
# # search process with specific user, option with exec_substring or cmdline_substring
# search_user = ""
procstat 插件其他关键配置
- gather_total 比如进程名字是 mysql 的进程,同时可能运行了多个,我们想知道这个机器上的所有 mysql 的进程占用的总的 cpu、mem、fd 等,就设置 gather_total = true,当然,对于 uptime 和 limit 的采集,gather_total 的时候是取的多个进程的最小值
- gather_per_pid 还是拿 mysql 举例,一个机器上可能同时运行了多个,我们可能想知道每个 mysql 进程的资源占用情况,此时就要启用 gather_per_pid 的配置,设置为 true,此时会采集每个进程的资源占用情况,并附上 pid 作为标签来区分
- gather_md5 计算二进制文件的md5(binary_md5sum)以及cmdline的md5(cmdline_md5sum), 每个采集周期计算一次。因为涉及磁盘IO,可能会带来额外的资源开销,比如消耗更多cpu和IO资源,v0.3.61-v0.3.72版本默认开启,v0.3.73及以上版本默认是关闭。
- gather_more_metrics 默认 procstat 插件只是采集进程数量,如果想采集进程占用的资源,就要启用 gather_more_metrics 中的项,启用哪个就额外采集哪个
gather_more_metrics 中有一个 jvm 的采集类别,如果是 Java 进程,可以启用这个配置,会额外采集 Java 进程的 JVM 信息,采集方法是使用 jstat 命令,所以需要确保 Categraf 所在的机器上有 jstat 命令,并且要确保 Categraf 进程可以从环境变量 PATH 中找到 jstat 命令。对于使用 systemd 托管 Categraf 的用户要尤其注意,通常要在 systemd 的配置文件里设置类似这样的环境变量 Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/java/jdk1.8.0_281/bin"
,这样 Categraf 进程才能找到 jdk bin 目录下的 jstat 命令。
总结
进程监控是一种黑盒监控手段,可以监控进程的存活性以及进程的资源消耗情况。Categraf 是一个功能强大的 agent,包含了近百种采集插件,其中就包含了 procstat 插件,用于进程监控。本文介绍了进程监控的原理以及如何配置 Categraf 来监控进程。希望对大家有所帮助。