Zabbix Agent / Agent 2 采集原理与运行机制详解

引言

Zabbix Agent 与 Agent2 是 Zabbix 监控体系中最核心的数据采集组件。当你在服务器上安装并启动 Agent 后,它便成为一个驻留系统中的守护进程,持续对外提供数据采集服务。

两代 Agent 的核心本质是 「本地系统接口读取器 + Zabbix 协议通信端」:它本身不生成监控数据,所有指标均来自操作系统内核暴露的标准接口;Agent 负责封装读取逻辑、按约定协议与 Server 交互,最终将系统指标传递给监控平台。两代 Agent 的数据来源完全一致,差异在于内部并发架构、组织方式与扩展能力。

一、数据的根本来源:操作系统原生接口

不管 Agent 1 还是 Agent 2,安装并启动后,它的核心工作可以概括为三步:

  1. 启动并监听:Agent 进程启动后,在本地监听 TCP 10050 端口(被动模式用),同时主动连接 Server/Proxy 的 10051 端口(主动模式用)。
  2. 接收或获取监控项列表:Agent 需要知道"采集什么"。这个"什么"就是监控项(Item),每个监控项有一个唯一的 Key(如 system.cpu.utilvm.memory.size[available])。
  3. 按 Key 执行采集动作并返回数据:Agent 根据 Key 找到对应的采集方式(系统调用、读文件、执行命令等),拿到原始值,返回给 Server。

1.1 主流系统的数据接口

平台 数据接口 说明
Linux /proc 虚拟文件系统、/sys 设备文件系统、系统调用(getloadavg()statfs()sysinfo() 等) 内核态数据暴露的标准接口,无需特殊权限,是系统原生的暴露能力。
Windows PDH 性能计数器、Windows Native API、WMI 接口读取系统运行指标 通过性能计数器获取系统运行指标
其他 Unix/BSD 各自对应的系统调用与内核接口 平台特定的接口实现

1.2 典型指标与底层来源对应

所有内建监控项(key)本质上就是把这些读取逻辑用代码封装好,调用时直接返回解析后的值:

监控项示例 底层数据来源(Linux)
system.cpu.load 读取 /proc/loadavg 文件
system.cpu.util 读取 /proc/stat 文件,通过时间片差值计算使用率
vm.memory.size 读取 /proc/meminfo 文件
net.if.in / net.if.out 读取 /proc/net/dev 文件
vfs.fs.size 调用 statfs() 系统调用读取文件系统元数据
proc.num 遍历 /proc 下的进程目录统计数量
system.uptime 读取 /proc/uptime 文件
system.hostname 调用 gethostname() 系统调用

二、Zabbix Agent 1(C 语言版)架构与运行机制

传统 Agent 1 采用预派生多进程架构,安装后以系统服务运行,通过多进程分工完成监听、采集、上报全流程。

Agent 1 内部硬编码了一批内置监控项的实现逻辑。每个 Key 对应一段 C 代码,执行时通过以下方式获取数据:

采集方式 原理 典型 Key 示例
系统调用(syscall) 直接调用操作系统内核提供的 API 获取信息,效率最高 system.cpu.util(读取 /proc/stat 并计算差值)
读取系统文件 读取 /proc/sys 等虚拟文件系统中的文件 vm.memory.size[available](读取 /proc/meminfo
执行外部命令 fork 子进程执行 Shell 命令或脚本 UserParameter 定义的自定义监控项

2.1 启动与初始化流程

  1. 服务启动后,主进程(agent #0)首先读取 zabbix_agentd.conf 配置文件,校验参数、初始化资源。
  2. 按配置 fork 出功能独立的子进程:
    • 多个 listener 进程:数量由 StartAgents 参数控制(默认 3 个),负责被动模式请求处理。
    • 1 个 collector 预采集进程:固定数量,不可配置,全局负责基础指标预采集与缓存。
    • 1 个 active checks 主动检查进程:固定数量,不可配置,负责主动模式全链路逻辑。
  3. 各子进程独立运行,主进程监控子进程状态,异常退出时自动重启。

2.2 核心子进程职责

  • 主进程:管理子进程生命周期,监控运行状态,异常时自动重启。
  • listener 进程:被动模式专属,常驻监听 10050/TCP 端口,接收并处理 Server 发起的采集请求,多个进程并行处理。
  • collector 进程:全局共享的预采集缓存进程,后台常驻以高频周期预采集 CPU、磁盘等常用基础指标并缓存结果;被动请求和主动采集均可直接复用缓存,降低系统调用开销,提升响应速度。
  • active checks 进程:主动模式专属,全链路负责配置拉取、本地采集调度、缓冲区管理、批量上报。

2.3 被动模式采集运行机制

被动模式是 Server 主动拉取、Agent 被动响应的经典采集方式,调度权完全在 Server 侧。

  1. 监听等待:多个 listener 进程常驻监听 10050/TCP 端口,等待 Server 端发起连接。
  2. 请求接收:Server 端 agent poller 进程发起连接,发送监控项 Key 字符串。
  3. 解析执行listener 解析 Key 与参数,匹配对应内建采集函数;若为 UserParameter 则 fork 子进程执行外部命令。
  4. 结果返回:采集完成后按 Zabbix 文本协议封装结果,返回给 Server,单次交互完成。
  5. 并发控制:并发能力由 StartAgents 决定,超出数量的连接会进入队列等待。
Server/Proxy                          Agent (10050端口)
    |                                      |
    |--- TCP连接,发送请求: "system.cpu.load[all,avg1]" -->|
    |                                      |--- 解析Key → 执行采集(读/proc/loadavg)
    |<--- 返回结果: "0.15 0.10 0.08" ----------------|
    |--- 关闭连接                         |

2.4 主动模式采集运行机制

主动模式下采集调度权下沉至 Agent 侧,Agent 自主完成配置拉取、本地采集与批量上报。

  1. 配置拉取active checks 进程按 RefreshActiveChecks 周期(默认 120 秒;Zabbix 6.4 起支持增量同步,默认 5 秒)主动连接 Server 10051 端口,携带主机名拉取主动监控项列表。
  2. 本地调度:在本地为每个监控项维护独立定时器,按配置间隔定时执行采集,可复用 collector 进程的预采集缓存。
  3. 缓冲批量:采集结果先写入内存缓冲区,达到 BufferSize 数量阈值或 BufferSend 时间阈值时,批量打包上报。
  4. 断网容错:网络中断时数据暂存内存缓冲区,恢复后自动补传;进程重启后缓存数据丢失。
Agent                                 Server/Proxy (10051端口)
  |                                        |
  |--- TCP连接,发送: "我是host-A,给我监控项列表" -->|
  |<--- 返回: [{key:system.cpu.util, delay:60s}, ...] --|
  |--- 关闭连接(配置同步完成)             |
  |                                        |
  |  [本地按间隔调度采集,复用collector缓存]
  |  [数据写入内存缓冲区]
  |  [达到阈值时批量上报]
  |--- TCP连接,发送: "批量采集数据" ---->|
  |<--- 返回: "success" --------------------|

三、Zabbix Agent 2(Go 语言版)架构与运行机制

Agent 2 是官方重构版本,核心采集逻辑不变,架构从「多进程」改为单进程 + 插件化协程,扩展性与性能更优。

3.1 启动与初始化流程

  1. 服务启动后,仅运行单个 zabbix_agent2 主进程,读取 zabbix_agent2.conf 配置。
  2. 内部通过 Goroutine 协程启动多个功能模块:被动监听协程、主动检查协程、插件管理器、各采集插件协程。
  3. 所有模块在同一进程内并发运行,通过协程调度实现多任务,ps 命令只能看到一个主进程。

3.2 插件化采集体系

Agent 2 的核心变化是所有采集能力插件化,官方内置系统、日志、文件、网络、Docker、Systemd、数据库等十几种采集插件,第三方也可开发自定义插件。

内置插件示例:

插件 采集对象 数据来源
CPU 插件 CPU 使用率、负载 /proc/stat/proc/loadavg
内存插件 内存使用情况 /proc/meminfo/proc/vmstat
磁盘插件 磁盘 I/O、容量 /proc/diskstats/proc/mountsstatfs()
网络插件 网络流量 /proc/net/dev
Docker 插件 容器状态 Docker API(Unix Socket)
Systemd 插件 服务状态 systemd D-Bus 接口
MySQL/Redis 等插件 数据库/中间件状态 对应服务的协议或 API

插件接口:

接口 作用
Exporter 核心接口,定义 Export() 方法,负责执行采集并返回数据
Configurator 可选接口,定义 Configure() 方法,用于接收 Agent 传来的配置
Runner 可选接口,定义 Start()/Stop() 方法,用于需要长期运行的采集任务(如持续监听日志)

Agent 2 通过 UNIX Socket(Linux)或 Named Pipe(Windows)与外部插件进行双向通信:

Agent 2 主进程
    |
    |--- UNIX Socket ---> 插件A(如 Docker 插件)
    |--- UNIX Socket ---> 插件B(如 MySQL 插件)
    |--- UNIX Socket ---> 插件C(自定义插件)

并发控制:
每个插件有独立的 Capacity 参数(默认 100),限制该插件最大并发执行的采集任务数。可通过 Plugins.<PluginName>.Capacity=N 配置调整。不同插件的检查可以并行执行,互不影响。

3.3 被动模式采集运行机制

  1. 监听协程常驻 10050 端口,接收 Server 连接请求。
  2. 为每个连接创建一个 goroutine 独立处理,并发能力由 Go runtime 自动调度,不受固定进程数限制。
  3. 解析 key 后,分发到对应采集插件。
  4. 插件内部调用系统接口或执行脚本,完成数据采集。
  5. 按 Zabbix 协议封装结果,返回给 Server。

3.4 主动模式采集运行机制

  1. 配置拉取:主动检查协程定期连接 Server 拉取监控配置。Zabbix 6.4 起支持增量同步,仅传输变更部分。
  2. 插件调度:配置分发给各采集插件,插件内部维护采集定时器,按各自的更新间隔执行采集。
  3. 缓冲上报:采集结果汇总到全局缓冲区,达到阈值后批量上报。
  4. 持久化缓存:支持 EnablePersistentBuffer 参数,网络长时间中断时数据写入本地磁盘文件,进程重启也不丢失,恢复后自动补传。

四、两类监控项的具体采集原理

两代 Agent 通用,监控项分为内建指标自定义参数两类,实现机制与性能差异显著。

4.1 内建 Key(内置指标)

  • 原理:由 Agent 原生代码直接封装系统调用与内核接口读取逻辑,编译进二进制可执行文件。

  • 执行流程

    收到 Key 请求 → 匹配内置处理函数 → 调用系统接口/读取内核文件 → 解析数值、格式化 → 返回结果
    
  • 特点:纯内存/文件级操作,无额外进程开销,毫秒级响应,性能极高,是监控体系的核心主力。

  • 限制:仅支持官方预设的系统级指标,无法自定义业务逻辑。

4.2 UserParameter(自定义参数)

  • 原理:用户自定义外部命令或脚本,Agent 收到请求时创建子进程(Agent 1)或启动协程(Agent 2)执行命令,捕获标准输出作为监控值。

  • 配置示例

    UserParameter=mysql.ping,mysqladmin -uroot ping | grep -c alive
    
  • 执行流程

    收到自定义 Key → 匹配配置中的命令模板 → 替换参数 → 创建执行环境运行命令 → 捕获 stdout 输出 → 去除首尾空白 → 返回结果
    
  • 关键规则

    • 外部命令通过 shell(默认 /bin/sh)执行,存在进程创建、shell 解析等资源开销。
    • 执行超时由 Timeout 参数控制(默认 3 秒),超时强制终止,避免资源泄漏。
    • 命令输出多行时,Agent 仅返回第一行作为结果。
  • 特点:灵活度极高,可实现任意业务指标;但性能开销远大于内建 Key,大量慢执行脚本会拖慢整体采集能力,需合理控制数量与耗时。

4.3 日志监控(log/logrt)

日志监控是特殊的采集类型,核心原理是跟踪文件新增内容,Agent 内部为每个日志项维护文件偏移量,确保不重复、不遗漏。

  • 被动模式:Server 每次请求时,Agent 读取自上次偏移量后的新增内容,并更新偏移位置。
  • 主动模式:Agent 本地自行跟踪文件变化,将新增行批量推送给 Server,效率更高;Agent 2 的 Runner 接口插件尤其适合此类长期运行的采集任务。

五、端到端完整采集流程示例

示例 1:被动模式下 CPU 负载采集全流程

Server agent poller 按调度时间,向目标 Agent 10050 端口发起 TCP 连接
        ↓
发送请求字符串:system.cpu.load[all,avg1]
        ↓
Agent listener 进程(Agent 1)/协程(Agent 2)接收请求
        ↓
匹配内建 CPU 负载处理函数
        ↓
读取 /proc/loadavg 文件,解析出 1 分钟平均负载
        ↓
按 Zabbix 文本协议封装结果,返回给 Server
        ↓
Server 收到数据,进入预处理、缓存、触发器计算等后续流水线

示例 2:主动模式下内存使用率采集全流程

Agent 启动后,主动检查协程连接 Server 10051 端口,携带主机名拉取主动监控项列表
        ↓
拿到配置后,本地为 vm.memory.size 设置 60 秒采集定时器
        ↓
定时触发后,内存插件读取 /proc/meminfo,计算使用率,结果写入缓冲区
        ↓
缓冲区累计到阈值或达到最大保留时间时,批量打包发送给 Server
        ↓
Server trapper 进程接收数据,解析匹配后进入处理链路

六、两代 Agent 核心差异对比表

对比维度 Agent 1(zabbix_agentd) Agent 2(zabbix_agent2)
开发语言 C 语言 Go 语言
进程模型 预派生多进程(fork) 单进程 + 多协程(Goroutine)
进程可见性 可通过 ps 查看主进程、listener、collector、active checks 等独立子进程 仅可见单一主进程,内部并发不可见
被动并发控制 全局 StartAgents 参数控制 listener 进程数 插件级 Capacity 参数分别控制各插件并发数
主动模式实现 active checks 进程统一负责调度、采集与上报,共享 collector 预采集缓存 主动检查协程调度 + 各插件独立定时器采集
扩展方式 仅支持 UserParameter 外部脚本 原生插件体系 + UserParameter 兼容,支持第三方插件
配置同步 全量拉取 支持增量同步
持久化缓存 不支持,仅内存缓存,进程重启丢失 支持 EnablePersistentBuffer,数据可落盘持久化
内置采集能力 基础系统指标 基础指标 + Docker/Systemd/数据库等扩展插件
资源开销 多进程内存占用稍高,上下文切换开销大 单进程内存管理更高效,协程切换开销低
官方定位 兼容旧环境,轻量基础采集 新一代推荐版本,插件化、高并发、高扩展

七、总结

  1. Agent 是一个守护进程:它按照 Server 下发的监控项列表,在本地执行对应的采集动作,然后把结果返回。Agent 本身不存储数据、不判断告警、不做预处理,这些全部由 Server 完成。

  2. 数据源头是操作系统内核接口:两代 Agent 采集数据的本质完全相同,都是读取 /proc/sys、系统调用等内核暴露的标准接口,而非 Agent 自身生成数据。

  3. 内置监控项:Agent 内部硬编码了读取操作系统指标的逻辑(读 /proc、调系统 API),每个 Key 对应一段采集代码。⭐

  4. UserParameter:管理员通过配置 Shell 命令,让 Agent 执行自定义命令获取数据。⭐

  5. 日志监控基于文件偏移跟踪:Agent 记住上次读取位置,只采集新增内容,主动模式对此有原生优化。

  6. Agent 1 靠多进程实现并发,架构经典、资源隔离好;Agent 2 靠协程 + 插件实现并发,扩展性更强、性能更优、功能更丰富。

  7. Agent 2 插件:通过 Go 插件机制,将采集逻辑模块化、并发化,效率更高。

posted @ 2026-08-31 15:14  kyle_7Qc  阅读(5)  评论(0)    收藏  举报