转自@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,
- 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)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()函数中实现的。
至此,监控项数据采集流程就解析完了,以上仅供参考,欢送斧正。