乐趣区

关于zabbix:干货丨Zabbix-源码解析之监控项数据采集流程

转自 @twt 社区,作者:张帆

一、概述

监控项数据采集是一个监控工具最根本的性能,监控数据采集的精确、实时、无效是 Zabbix 其它监控性能失常运行的前提。因而,Zabbix 运维人员有必要理解监控项数据采集流程,并有针对性的设计巡检和问题解决流程,确保监控数据品质。

Zabbix 的监控采集类型很丰盛,我最罕用的是 Agent 形式,因而,就筛选 Linux 的内存监控(Zabbix 内置 key:vm.memory.size)为例来梳理一下监控项数据采集流程。

二、程序流程图

下图是咱们梳理的 vm.memory.size 监控项采集流程图,数据采集的过程设计得周密而简单:

上面,咱们将对次要流程和具体实现进行解析,波及函数的具体实现解析写在了代码正文中。

三、相干数据结构定义

在介绍 vm.memory.size 具体实现之前,咱们先介绍几个相干数据结构的定义。

(1)struct ZBXMETRIC

该构造体用于记录 zabbix 的监控项配置信息

(2) struct AGENTREQUEST

该构造体用于记录 zabbix Agent 的监控项申请信息

(3) struct AGENTRESULT

该构造体用于记录给 zabbix Agent 返回的采集数据

四、监控项 vm.memory.size 配置

用法: vm.memory.size[]

mode 参数:

•total (*) – 总物理内存. mode 的默认值

•free (*) – 可用内存.

•active – 内存以后应用或最近应用,它在 RAM 中是沉闷的。

•inactive – 未应用内存.

•wired – 被标记为始终驻留在 RAM 中的内存,不会挪动到磁盘。

•pinned – 同“wired”。

•anon – 与文件无关的内存(不能从新读取)。

•exec – 可执行代码,通常来自于一个 (程序) 文件。

•file – 缓存最近拜访文件的目录。

•buffers (*) – 缓存磁盘读写数据。

•cached (*) – 缓存文件系统读写数据。

•shared – 能够同时被多个过程拜访的内存。

•used (*) – 已应用内存。

•pused (*) – 已应用内存占总内存的百分比。

•available (*) – 可用内存

•pavailable (*) – 可用内存占总内存的百分比。

如果咱们在某 Host 下定义了 2 个 item:

Item1:Total memory Key1:vm.memory.size[total]

Item2:Available memory Key2:vm.memory.size[available]

这 2 个 item 就会被 insert 到 Server 数据库的 items 表中,这样该 Host 的 Agent 就能够获取到相应的采集工作了(获取流程本文不具体论述),上面咱们来重点看下 vm.memory.size 的采集实现和数据上送。

五、监控项 vm.memory.size 采值实现

vm.memory.size 监控项在不同的操作系统下实现各不相同,Linux 零碎下的实现,在 src/libs/zbxsysinfo/linux/linux.c 中。其配置项寄存于 parameters_specific 数组中,能够看到对应的实现函数为 VM_MEMORY_SIZE,

  1. VM_MEMORYSIZE 函数(地位在:src/libs/zbxsysinfo/linux/memory.c)

用来承受参数,并对应调用对应的取值函数进行数据采集,并返回数据。

具体实现如下:

从源码中能够看到,Linux 零碎反对的模式包含如下参数,与官网文档中所列的参数不同。

•total

•free

•buffers

•used

•pused

•available

•pavailable

•shared

•cached

•active

•anon

•inactive

•slab

通过剖析各个参数对应的取值逻辑,可分为 2 种办法:

•第一种:调用 sysinfo 函数获取指标值。通过这种形式获取的选项参数有:total,free,buffers,used,pused,pavailable,shared。

•第二种:读取 /proc/meminfo 文件中的指标值。通过这种形式获取的选项参数有:available,cached,active,anon,inactive,slab。

上面咱们别离对两种状况进行剖析。

(1)调用 sysinfo 函数

Linux 中 sysinfo()函数是用来获取零碎相干统计信息的函数。它会将后果存储在 struct sysinfo 构造体中。

函数申明:

int sysinfo(struct sysinfo *info);

struct sysinfo 的定义如下:

total,free,buffers,used,pused,pavailable,shared 等指标,都是以 struct sysinfo 中的成员的取值来计算的。

• total:info.totalram * info.mem_unit

• free:info.freeram * info.mem_unit

• buffers:info.bufferram * info.mem_unit

• used:(info.totalram – info.freeram) * info.mem_unit

• pused:(info.totalram – info.freeram) / (double)info.totalram * 100

• pavailable:available / (info.totalram info.mem_unit) 100(available 在 /proc/meminfo 文件中读出)

• shared:info.sharedram * info.mem_unit(仅 Linux 2.4)

(2) 读取 /proc/meminfo 文件

该性能在 VM_MEMORY_PROC_MEMINFO 函数中实现。向 meminfo_entry 参数传递 ”Cached:”, “Active:”, “AnonPages:”, “Inactive:”, “Slab:” 字段。

其中 available 的获取比拟非凡,它先检测 /proc/meminfo 文件文件中是否有 ”MemAvailable:” 字段,如果没有,则再调用 sysinfo 函数获取。

具体实现如下:



六、监控项 vm.memory.size 数据上送

后面解析的监控项的采值逻辑,上面咱们来剖析数据从 Agent 端上送到 Server 的过程。

介绍几个相干的函数:

1.init_metrics 函数

vm.memory.size 监控项会被存储到 parameters_specific 数组中。那么 parameters_specific 数组在哪儿被应用到呢?就在 init_metrics 函数中。

init_metrics 函数在 zabbix Server 和 zabbix Agent 启动的过程中都被调用了,因而这些监控项在 zabbix 启动时曾经被设置好了。

2.add_metric 函数

add_metric 函数会向 commands 数组中增加值。commands 是在 sysinfo.c 中定义的一个 ZBX_METRIC 构造体变量,初始值是 NULL。

add_metric 函数具体实现如下:

3.process 函数

commands 数组在哪里被应用到了呢?在 process 函数中,process 函数定义在 src/libs/zbxsysinfo/sysinfo.c 中。



在 process 函数中会最终调用监控项实现函数,那 process 函数在哪被调用到的呢?

在 zabbix_agent 中,调用 process 函数的中央有 2 处,别离位于 agent 的被动模式和被动模式的实现中。咱们别离来剖析一下。

(1) 被动模式下的 processlistener 函数

(2)被动模式下的 processactivechecks 函数

  1. 监控项值的序列化与上送

介绍完相干的函数和调用,上面咱们能够具体来剖析数据上送的过程了

(1)agent 与 server 通信协议

首先是通信协议,agent 与 server 间的通信协议比较简单,其协定格局为:。

• PROTOCOL: 协定头,该字段长度为 4 个字节,内容为 ”ZBXD”。

• FLAGS: 协定标记,该字段长度为 1 个字节。有 2 个取值(这两个值能够应用“或”操作同时取):

– 0x01:ZBX_TCP_PROTOCOL,zabbix TCP 通信协议

– 0x02:ZBX_TCP_COMPRESS,应用压缩算法

• DATALEN: 数据长度,该字段长度为 4 个字节。整型,以小端模式示意。

– 留神该长度不蕴含协定头这几个字段的长度,它仅示意 DATA 字段的数据长度。

• RESERVED: 保留字段,用作协定扩大,字段长度为 4 字节。当 ZBX_TCP_COMPRESS 标记被设置后,RESERVED 字段会保留未被压缩时的数据段的长度。整型,以小端模式示意。

• DATA: 数据内容,应用 JSON 格局来序列化。

(2)监控项值的传递

1、咱们以被动模式下会被调用的 send_buffer 函数(zbx_tcp_send()最终会调用到 zbx_tcp_send_ext()函数)为例,剖析一下监控项值如何发送给 server。

被动模式下 zbx_tcp_send_to(s, *value, …)函数最终也会调用到 zbx_tcp_send_ext()函数,与被动模式下最终的解决是统一的,咱们不再独自剖析。

具体实现如下:






依据下面的源码剖析后果,可得出 agent 发送的数据的格局如下:

2、agent 发送数据后,会从 server 端收到响应数据,响应数据的格局如下:

在响应数据中,response 的状态能够是 success 或 failure。响应数据的检测与解析在 check_response 函数中操作。

(3) 数据上送的具体实现

zbx_tcp_send()最终会调用到 zbx_tcp_send_ext()函数,agent 与 server 间的通信协议的数据序列化是在 zbx_tcp_send_ext()函数中实现的。



至此,监控项数据采集流程就解析完了,以上仅供参考,欢送斧正。

退出移动版