跳转到内容

Zabbix 面试题

30 道题
分类
可观测性
子分类
metrics
题目数
30 道
已阅读 0 / 30 题
1 Zabbix 核心架构和核心组件是什么?

答案:

Zabbix 是一款企业级开源分布式监控解决方案,由 Server、Agent、Proxy、Web 前端和数据库五大核心组件构成,支持 SNMP、IPMI、JMX、Agent、Trapper、HTTP Agent 等多种采集协议,擅长主机、网络设备、数据库、应用服务的统一监控。

核心架构:

graph TD
    A["Zabbix Server
核心进程 + 告警引擎 + 数据库读写"] -->|读写历史数据| B[(数据库
MySQL/PostgreSQL/TimescaleDB)] C["Zabbix Agent / Agent 2"] -->|主动/被动推送指标| A D["Zabbix Proxy"] -->|汇聚后转发| A E["SNMP/IPMI/JMX 设备"] -->|轮询采集| A F["Trapper/HTTP Agent
(主动推送)"] -->|推送| A A -->|告警动作| G["Action 升级
邮件/Webhook/IM"] H["Web 前端 PHP"] -->|API/RPC| A I["用户/运维"] -->|可视化与配置| H

核心组件职责:

组件职责关键特性
Zabbix Server核心进程,负责轮询/接收指标、触发器评估、告警发送、与数据库交互多进程模型:poller、trapper、housekeeper、alerter、escalator 等
Zabbix Agent部署在被监控主机上的采集程序Zabbix Agent(C 语言)/ Zabbix Agent 2(Go 重写,插件化)
Zabbix Proxy分布式场景下代替 Server 收集区域数据,统一上报缓解 Server 压力,跨机房/网络隔离场景必备
Web 前端PHP 实现的可视化与配置界面配置主机、模板、触发器、仪表盘;调用 API
数据库持久化配置、历史、趋势、事件MySQL、PostgreSQL、TimescaleDB(PostgreSQL 扩展)

与 Prometheus 架构的本质区别:

维度ZabbixPrometheus
核心定位中心化的多协议监控平台Pull 模型时序数据库 + 告警评估
采集模型Agent/SNMP/IPMI/Trapper 多元采集,Server 主导主要 Pull 模式,Exporter 解耦
数据模型主机-监控项-触发器强类型指标名 + 多维 Label,无类型约束
告警评估Server 内置触发器表达式Prometheus 评估规则 + Alertmanager 路由
分布式Proxy 中转 + 6.0+ HA cluster联邦 / Thanos / Cortex / Mimir
2 Zabbix 监控数据流是怎样的?一个监控项从采集到入库再到告警的完整链路是什么?

答案:

Zabbix 的数据流覆盖"采集→缓存→处理→入库→评估→告警"六个阶段,每个阶段都有专门的进程负责。这种流水线设计让 Server 在百万级 NVPS(每秒新值数)规模下仍能稳定运行。

完整数据流:

flowchart LR
    A1["被监控端
(Agent/SNMP/IPMI)"] -->|1. 推送/拉取| A2["Zabbix Server
poller/trapper 接收"] A2 -->|2. 写入 Cache| A3["History Cache
(内存环形缓冲)"] A3 -->|3. 同步器处理| A4["Configuration Cache
DBSync/VC sync"] A4 -->|4. 触发器评估| A5["Trigger Engine
评估表达式"] A5 -->|5. 命中触发器| A6["Action 引擎
执行告警动作"] A5 -.未命中.-> A7[(数据库
历史/趋势表)] A3 -->|6. flush 周期| A7 A7 -->|7. Housekeeper| A8[(清理过期数据)]

各阶段关键进程:

阶段进程职责
采集poller / trapper / snmp / ipmi / jmx多协议接收/拉取指标
缓存History Cache内存缓冲新采集值,避免直接打 DB
同步syncer(configuration syncer)周期性把 DB 配置同步到内存缓存
评估trigger engine(escalator/alerts)按时间窗口评估触发器表达式
入库history syncer / dbsyncer把缓存值批量写入 history/trends 表
清理housekeeper删除过期历史与事件

关键参数:

HistoryCacheSize=128M           # 历史缓存大小(建议 128M-1G)
HistoryIndexCacheSize=32M       # 索引缓存
TrendCacheSize=64M              # 趋势缓存
ValueCacheSize=256M             # 值缓存(SNMP 等指标)
CacheUpdateFrequency=60         # 配置同步周期
HousekeepingFrequency=1         # 清理频率(小时)

典型时序:

T+0s      采集到新值,写入 History Cache
T+0s      同步到 ValueCache,触发器引擎评估
T+5s      flush 周期到达,批量写入 DB history 表
T+1h      Housekeeper 删除超过保留期的历史
3 Zabbix Server 的进程模型是怎样的?常见进程类型和作用是什么?

答案:

Zabbix Server 采用多进程(多类型 worker)模型,每类进程负责特定功能,进程数量通过配置文件独立调优。这种设计既能并行处理大规模采集,也能在某个进程类型成为瓶颈时单独扩容(按类型 fork 多个 worker)。

进程类型与职责:

进程数量配置职责
pollerStartPollers通用主动轮询(Agent、HTTP Agent)
trapperStartTrappers接收 Trapper 主动推送(10051 端口)
snmp pollerStartSNMPPollersSNMP 协议轮询
ipmi pollerStartIPMIPollersIPMI 协议轮询(带外管理)
jmx pollerStartJMXPollersJMX 监控 JVM 应用
icmp pingerStartPingersfping 主机存活检测
http pollerStartHTTPPollersHTTP Agent / Web 场景
history syncerHistorySyncer把缓存值写入 history/trends 表
configuration syncerConfigSyncer周期性把配置同步到内存
housekeeper-清理过期历史/事件/审计
alerterStartAlerters发送告警动作(邮件/SMS)
escalatorStartEscalators告警升级流程(按步骤)
lld workerStartLLD低层级发现(Low-Level Discovery)
task manager-远程命令、脚本、立即检查任务
preprocessorStartPreprocessors预处理步骤(正则、JS、自定义)
discovererStartDiscoverers网络自动发现(IP 段扫描)
timer-周期/间隔维护的定时器

进程数调优原则:

poller 数 ≈ NVPS / 1000  (经验公式,每 poller 约 1k NVPS)
trapper 数 ≥ 主动 Agent 数量 / 10
http poller 数 ≈ 活跃 Web 场景数 / 50
SNMP 设备多时加大 StartSNMPPollers
JMX 应用多时加大 StartJMXPollers

配置示例:

# /etc/zabbix/zabbix_server.conf

StartPollers=20
StartTrappers=10
StartPingers=5
StartHTTPPollers=5
StartSNMPPollers=10
StartIPMIPollers=2
StartJMXPollers=5
StartLLD=5
StartAlerters=5
StartEscalators=5
StartPreprocessors=10
HistorySyncer=8

判断进程瓶颈:

# 内部监控项 zabbix[process,<type>,<mode>,<state>]
# 例如:zabbix[process,poller,avg,busy] > 75% 表示 poller 繁忙
zabbix_get -s localhost -k 'zabbix[process,poller,avg,busy]'
zabbix_get -s localhost -k 'zabbix[queue]'
4 主机(Host)、主机组(Host Group)、模板(Template)、监控项(Item)、触发器(Trigger)的关系是什么?

答案:

Zabbix 的对象模型围绕"主机-模板-监控项-触发器"四元组展开,模板是核心抽象单元,支持复用、继承、链接到多台主机。理解这套模型是设计可维护监控体系的基础。

对象关系图:

graph TD
    A["Host Group
主机组(如 DB、Web)"] --> B["Host
主机(IP/Agent 接口)"] B -->|Link| C["Template
模板"] C -->|包含| D["Item
监控项"] C -->|包含| E["Trigger
触发器"] C -->|包含| F["Graph / Dashboard
图形与仪表盘"] C -->|包含| G["Discovery Rule
LLD 规则"] C -->|继承| H["Template Parent
父模板"] D -->|定义| I["Key: vfs.fs.size
Type: Zabbix Agent"] E -->|表达式| J["{last} > 90
持续 5m"] B -->|继承宏| K["Host Macro
{$DISK_THRESHOLD}"] C -->|模板宏| L["Template Macro
{$DEFAULT_THRESHOLD}"]

关键概念:

概念作用关键属性
Host被监控实体主机名、IP、Agent 接口、SNMP 接口、IPMI 接口、所属主机组
Host Group主机逻辑分组用于权限分配、批量操作、维护期
Template监控项/触发器/图形的可复用单元可包含 Item、Trigger、Graph、Dashboard、LLD、宏
Item单一指标的采集定义Key、Type、Interval、History、Trends、Applications
Trigger告警判定逻辑表达式、严重等级、标签、依赖
Macro变量替换用户宏({$…}),支持 7 级优先级
LLD自动发现自动创建 Item/Trigger 原型

模板继承与链接:

Template Module Linux (基础模板)
  ├─ Template Module Linux CPU
  ├─ Template Module Linux Memory
  ├─ Template Module Linux Filesystems (LLD)
  └─ Template Module Linux Network Interfaces (LLD)

主机 web-01 链接到 Template Module Linux
  → 自动继承所有子模板、Item、Trigger、LLD

实操建议:

  • 按应用类型划分模板(如 MySQL、Redis、Nginx、Linux 基础),不按业务项目划分
  • 主机只链接模板,避免在主机上独立写 Item/Trigger(可维护性差)
  • 宏优先用模板级,主机级只覆盖例外值
5 Zabbix 与 Prometheus 等云原生监控方案的本质区别是什么?

答案:

Zabbix 是"中心化、多协议适配、对象模型驱动"的传统企业监控平台;Prometheus 是"Pull 模式时序数据库 + 告警评估 + 生态驱动"的云原生监控体系。两者在数据模型、采集范式、扩展方式、定位上有本质区别。

核心差异对比:

维度ZabbixPrometheus
诞生背景传统企业 IT 基础设施监控云原生(Kubernetes 时代)
核心定位中心化的多协议监控平台时序数据库 + 告警评估引擎
采集模型Server 主导(推 + 拉),多协议(Agent/SNMP/IPMI/Trapper)Pull 模型为主 + Pushgateway 补充 + Remote Write
数据模型主机-Item-Trigger 强类型对象指标名 + Label 多维,无类型约束
存储MySQL/PostgreSQL/TimescaleDB(行式/混合)自研 TSDB(块式)
告警评估Server 内置触发器 + Action 升级规则文件 + Alertmanager 路由
可视化自带 Dashboard + Grafana 集成主要依赖 Grafana
扩展方式自定义 Key、自定义脚本、Agent 2 插件Exporter(任何语言)+ 远程写入
云原生适配通过 Zabbix Agent + HTTP Agent 支持,需手动配置天然适配 K8s Service/Pod 自动发现
K8s 场景可用但非首选行业标准

适用场景对比:

Zabbix 优势场景:
  - 传统 IDC(物理机、网络设备、存储)
  - 大量 SNMP/IPMI 设备(交换机、路由器、BMC)
  - 中小规模业务(数千到数万台主机)
  - 需要开箱即用的告警升级/值班
  - 数据库、中间件、应用有官方模板

Prometheus 优势场景:
  - Kubernetes / Service Mesh / 微服务
  - 容器化业务(Pod 生命周期短)
  - 多维标签聚合分析(按 Service/Env/Region)
  - 大规模时序聚合(PromQL 灵活)
  - 与 Grafana / Loki / Tempo 生态集成

融合趋势:

现代监控栈:
  指标:  Prometheus / VictoriaMetrics / Thanos
  日志:  Loki / ELK / OpenSearch
  追踪:  Tempo / Jaeger / SkyWalking
  传统: Zabbix(保留对物理设备/网络/中间件的统一监控)
  
  → Zabbix 与 Prometheus 长期并存,互为补充
6 Zabbix Agent 与 Zabbix Agent 2 有什么区别?

答案:

Zabbix Agent 是 C 语言编写的传统采集程序;Zabbix Agent 2 是 Zabbix 4.4+ 引入的 Go 语言重写版本,采用插件化架构,性能和扩展性大幅提升。两者在 6.0+ 共存,新部署建议优先 Agent 2。

核心差异:

维度Zabbix Agent (C)Zabbix Agent 2 (Go)
开发语言CGo
引入版本1.x4.4(实验),5.0+(生产可用)
架构单进程,单一配置文件多插件并行,goroutine 调度
并发采集串行(被动模式下每连接一线程)原生并发,单连接内多指标并行
协议Zabbix 私有协议Zabbix 协议 + 自定义协议
扩展方式UserParameter / Loadable Modules插件(Plugin),官方提供 30+ 插件
采集间隔被动模式由 Server 控制可独立调度(go runtime 优势)
资源占用内存极小(约 1-2 MB)内存稍大(约 10-30 MB)
适用规模中小规模大规模、高并发
二进制名zabbix_agentdzabbix_agent2

官方内置插件(Agent 2):

Agent 2 内置插件:
  - PostgreSQL / MySQL / Oracle / MSSQL / MongoDB
  - Redis / Memcached / RabbitMQ / Kafka / MQTT
  - Docker / systemd / Ceph / Proxmox
  - HTTP / ICMP / SNMP / Modbus / Smart
  - FilePath / Directory / LogFile / WindowsEventLog
  - ... (持续扩展)

配置差异:

# /etc/zabbix/zabbix_agent2.conf (Agent 2)
Plugins.PostgreSQL.Sessions.<SessionName>.URI=postgresql://user:pass@host:5432/db
Plugins.Redis.Sessions.<SessionName>.URI=redis://host:6379

# /etc/zabbix/zabbix_agentd.conf (传统 Agent)
UserParameter=mysql.questions,mysqladmin -uroot status | awk '{print $6}'

监控项示例:

# Agent 2 使用插件 Key (内置)
postgresql.ping[session1]
redis.info[session1,used_memory]
mysql.custom.query[session1,"SHOW GLOBAL STATUS LIKE 'Threads_connected'"]

# 传统 Agent 需 UserParameter 自定义
mysql.questions

迁移建议:

  • 新部署:直接用 Agent 2
  • 存量 C-Agent:可平滑迁移,关键监控项需重新规划 Key(插件 Key 与 UserParameter 不通用)
  • 特殊场景(如极小内存、资源敏感嵌入式):仍可考虑传统 Agent
7 Zabbix Agent 主动模式与被动模式的区别?什么场景用哪个?

答案:

被动模式(Passive)由 Server/Proxy 主动向 Agent 拉取数据;主动模式(Active)由 Agent 周期主动连接 Server/Proxy 推送数据。两种模式各有适用场景,大规模监控通常两者结合使用。

模式对比:

sequenceDiagram
    participant S as Zabbix Server/Proxy
    participant A as Zabbix Agent

    rect rgb(240, 248, 255)
    Note over S,A: 被动模式
    S->>A: agent.ping
    A-->>S: 响应
    S->>A: agent.version
    A-->>S: 响应
    S->>A: vfs.fs.size[/,free]
    A-->>S: 1024
    end

    rect rgb(255, 248, 240)
    Note over S,A: 主动模式
    A->>S: agent.hostname / 主动注册
    S-->>A: 响应配置
    A->>S: active checks: host:port
    S-->>A: 返回要采集的 Item 列表
    loop 周期采集
        A->>S: send data: key=value
        S-->>A: 确认
    end
    end

详细对比:

维度被动模式 (Passive)主动模式 (Active)
连接发起方Server/ProxyAgent
Server 端口1005110051
Agent 监听10050无需监听(出站连接)
防火墙要求需 Agent 端入站可达 10050只需 Agent 出站可达 Server 10051
NAT 友好
Agent 配置Server=<Server IP>ServerActive=<Server IP>
Server 端间隔由 Server 端 Update interval 控制由 Agent 端 RefreshActiveChecks 控制刷新频率
数据延迟与 Server 调度一致取决于 Agent 主动推送周期
Item 类型Zabbix Agent / SNMP / IPMI / JMXZabbix Agent (Active) / Trapper / Log
适合规模小到中等规模大规模、跨 NAT、移动设备
日志监控不支持支持(log, log.count, logrt, eventlog)

配置示例:

# /etc/zabbix/zabbix_agentd.conf

# 被动模式(必须配置)
Server=192.168.1.100
ListenPort=10050
ListenIP=0.0.0.0

# 主动模式(必须配置)
ServerActive=192.168.1.100:10051
HostnameItem=system.hostname
RefreshActiveChecks=120

# 同时启用:可减少 Server 轮询压力

Item 类型选择:

Item Type:
  Zabbix agent           → 被动
  Zabbix agent (active)  → 主动
  SNMP agent             → 被动
  IPMI agent             → 被动
  JMX agent              → 被动
  Zabbix trapper          → 主动推送(由 Agent/Script sender)
  Zabbix aggregate       → 计算型
  HTTP agent             → 被动

最佳实践:

  • 内网主机:被动 + 主动并用(日志类必须主动)
  • 跨防火墙/NAT:仅用主动
  • 大规模(> 5000 Agent):优先主动模式,降低 Server 轮询压力
  • 日志监控(log、log.count、logrt):必须用主动模式
8 Zabbix 如何使用 SNMP 监控?工作原理和关键配置是什么?

答案:

SNMP(Simple Network Management Protocol)是网络设备(交换机、路由器、打印机、存储)的事实标准协议。Zabbix 通过 snmp poller 进程按 OID(对象标识符)轮询设备 MIB 中的指标,实现对网络设备的统一监控。

SNMP 监控原理:

sequenceDiagram
    participant Z as Zabbix Server/Proxy
    participant D as SNMP 设备(交换机)

    Note over Z,D: SNMP v2c 轮询
    Z->>D: GET OID 1.3.6.1.2.1.2.2.1.10.2 (ifInOctets.2)
    D-->>Z: 返回端口 2 入口流量
    Z->>D: GET OID 1.3.6.1.2.1.2.2.1.16.2 (ifOutOctets.2)
    D-->>Z: 返回端口 2 出口流量
    Note over Z,D: 速率计算
    Z->>Z: delta(value) / interval = bps

SNMP 版本对比:

版本安全性能适用
v1社区名(明文)老旧设备
v2c社区名(明文)高(支持 GetBulk)主流网络设备
v3用户认证(MD5/SHA)+ 加密(DES/AES)较高金融/高安全场景

Zabbix SNMP 关键配置:

# /etc/zabbix/zabbix_server.conf
StartSNMPPollers=10
SNMPTrapperFile=/tmp/zabbix_traps.tmp

# 时间相关参数(超时与重试)
Timeout=3
SNMPTimeout=1       # 覆盖全局 Timeout

# 单设备并发(避免拖垮)
MaxConcurrentChecksPerPoller=10

Zabbix 主机 SNMP 接口配置:

Host Configuration:
  SNMP interface: 192.168.1.1:161
  Use bulk requests (SNMPv2c/v3): ✓
  SNMP version: SNMPv2c
  Community: public

典型监控项 Key:

# 通用 OID 形式
IF-MIB::ifInOctets.2                          # 端口 2 入口字节
IF-MIB::ifOutOctets.2                         # 端口 2 出口字节
SNMPv2-MIB::sysName.0                         # 设备名
HOST-RESOURCES-MIB::hrStorageSize.1           # 存储大小
HOST-RESOURCES-MIB::hrStorageUsed.1           # 存储已用

# 计算速率(Zabbix 触发器)
{host:net.if.in[ifInOctets.2].change(60)} > 100000000  # 入流量 > 100MB/min

SNMP Trap 接收:

# 1. Zabbix 配置 snmptrapd
cat /etc/snmp/snmptrapd.conf
# traphandle default /usr/sbin/zabbix_trap_receiver.pl
# 或者用 snmptrapd 内置方式(Zabbix 5.0+)
disableAuthorization yes
traphandle default /usr/sbin/zabbix_trap_receiver

# 2. Zabbix Server 启用 trapper
StartSNMPTrapper=1
SNMPTrapperFile=/tmp/zabbix_traps.tmp

# 3. 创建 Item: Type = SNMP trap

常用网络设备模板:

Template SNMP Interfaces     # 通用接口流量(LLD 自动发现)
Template SNMP Generic        # 通用 OID 监控
Template SNMP OS Linux       # 主机资源
Template SNMP OS Cisco       # Cisco 设备
Template SNMP OS Huawei      # 华为设备
Template SNMP OS H3C         # H3C 设备

性能优化:

  • 启用 Use bulk requests(GetBulk 一次取多 OID)
  • 调整 TimeoutSNMPTimeout,网络抖动时增大重试
  • 高频率采集时增大 StartSNMPPollers
  • OID 历史用宏抽取(如 {#SNMPINDEX} 替换硬编码)
9 Zabbix 如何监控硬件带外管理(IPMI)?适用哪些场景?

答案:

IPMI(Intelligent Platform Management Interface)是服务器带外管理标准,独立于 OS 运行,通过 BMC(Baseboard Management Controller)提供温度、电压、风扇、电源、传感器等硬件级健康数据。Zabbix 通过 ipmi poller 进程定期轮询 BMC 的 IPMI/Sensor 数据。

IPMI 监控原理:

graph LR
    A["Zabbix Server
(ipmi poller)"] -->|"IPMI 协议 (UDP 623)"| B["BMC
独立固件"] B --> C["CPU 温度"] B --> D["风扇转速"] B --> E["电源状态"] B --> F["电压"] B --> G["机箱入侵"] B --> H["内存 ECC 错误"] B --> I["磁盘 SMART"]

IPMI 监控项类型:

IPMI 监控项示例(标准模板):
  - ipmi.sensor[CPU1 Temp]
  - ipmi.sensor[System Temp]
  - ipmi.sensor[Power Supply 1]
  - ipmi.sensor[FAN1 Speed]
  - ipmi.sensor[+12V]
  - ipmi.sensor[Chassis Intrusion]

关键配置:

# /etc/zabbix/zabbix_server.conf
StartIPMIPollers=5

# /etc/zabbix/zabbix_agentd.conf
# IPMI 由 Server 端直接轮询 BMC,无需 Agent
# Agent 端无需配置

主机 IPMI 接口配置:

Host Configuration:
  IPMI interface: 10.0.0.1:623
  IPMI sensor:   # 默认不填,自动发现
  IPMI authentication algorithm: Default
  IPMI privilege level: Operator
  IPMI username: zabbix
  IPMI password: ********

适用场景:

✔ 必须 IPMI 监控的场景:
  - 物理机/裸金属服务器(核心生产)
  - 温度异常敏感的高密度机房
  - 硬件故障预警(CPU 过热、内存 ECC、电源失效)
  - 静默故障捕获(系统挂掉后 Agent 无法上报,IPMI 仍可报告)

✘ 不适合 IPMI 的场景:
  - 虚拟机(无 BMC)
  - 云主机(厂商 API 替代)
  - 网络设备(用 SNMP)
  - 嵌入式/工控机

IPMI 性能与稳定性:

  • IPMI 协议本身较慢(每次请求需认证),单次超时建议 5-10s
  • BMC 抗压能力弱,并发采集需限制 StartIPMIPollers 数量
  • 部分老旧 BMC 固件存在已知漏洞,建议独立网段 + ACL 限制
  • 关键服务器配合 IPMI Watchdog(系统无响应时自动重启)

与 Redfish 的关系:

  • IPMI:传统协议,基于 UDP 623
  • Redfish:现代 REST API 标准(JSON over HTTP),DMTF 推动
  • Zabbix 5.0+ 已支持 Redfish(通过 HTTP Agent),逐步替代 IPMI
  • 新部署服务器优先使用 Redfish
10 Zabbix Trapper 和 HTTP Agent 是什么?什么时候用主动推送?

答案:

Trapper 是 Zabbix 提供的"主动推送"协议,业务方通过 zabbix_sender 或自定义协议向 Server 10051 端口推送数据;HTTP Agent 通过 HTTP/HTTPS 拉取数据,扩展对 RESTful API、JSON、XML 的支持。两者覆盖了"无法 Agent 主动采集"的场景。

Trapper 工作原理:

sequenceDiagram
    participant A as 业务脚本/客户端
    participant S as Zabbix Server
    participant DB as 数据库

    Note over A,S: Trapper 主动推送
    A->>S: zabbix_sender -z server -s host -k trap.item -o "value"
    S->>S: trapper 进程接收
    S->>DB: 写入 history 表
    Note over A,S: 批量推送(更高效)
    loop 多 Item
        A->>A: 构造 sender data file
        A->>S: zabbix_sender -T -i data.txt
        S-->>A: 处理结果统计
    end

Trapper 关键配置:

# /etc/zabbix/zabbix_server.conf
StartTrappers=5
TrapperTimeout=30

# Item Type 配置(Web UI):
Type: Zabbix trapper
Key:  trap.queue.depth
Type of information: Numeric (unsigned)

zabbix_sender 用法:

# 单值推送
zabbix_sender -z 192.168.1.100 -s "web-01" -k trap.queue.depth -o 42

# 批量推送(推荐)
cat > /tmp/data.txt <<EOF
"web-01" trap.queue.depth 1234567890 42
"web-01" trap.cache.hit 1234567890 0.85
"web-01" trap.api.qps 1234567890 1523
EOF

zabbix_sender -z 192.168.1.100 -T -i /tmp/data.txt

HTTP Agent 适用场景:

HTTP Agent 通过 HTTP 拉取数据:
  - 监控 Web 业务健康(状态码、响应时间、Body 内容)
  - 拉取 RESTful API 数据(JSONPath 提取)
  - 与云厂商 API 集成(AWS CloudWatch、阿里云监控)
  - 模拟用户访问链路(多步调用、Cookie 处理)
  - 自定义数据源(业务系统暴露 /metrics 端点)

HTTP Agent 监控项配置:

Item Type: HTTP agent
URL: https://api.example.com/v1/health
Request method: GET
Request headers: Authorization: Bearer xxxxx
Timeout: 5s
Status codes: 200
Response body:
  Type: JSON
  JSONPath: $.data.health
Required status codes: 200

多步 HTTP 场景:

Scenario(场景):
  Steps:
    Step 1: POST /api/login  → 提取 Token(Variables: token=$.data.token)
    Step 2: GET /api/orders  → 携带 Token + Headers
    Step 3: 提取订单数(JSONPath: $.total)

适用: 复杂 Web 业务可用性监控、登录后业务流断言

Trapper vs HTTP Agent vs Pushgateway 对比:

维度Zabbix TrapperZabbix HTTP AgentPrometheus Pushgateway
方向业务主动推送Zabbix 主动拉取业务主动推送
协议Zabbix 私有协议HTTP/HTTPSHTTP 协议
数据格式键值对HTTP 响应(JSON/XML/Text)Prometheus 文本格式
典型场景业务自定义指标、批处理Web/API 监控短生命周期任务、批处理
权限需配置 Host 允许推送需访问目标 URL需配置 Pushgateway ACL
扩展性zabbix_sender 任何语言依赖 HTTP 客户端prometheus_client 各语言 SDK
11 Zabbix 模板(Template)如何设计?模板继承与链接机制是怎样的?

答案:

模板是 Zabbix 的核心抽象单元,把"监控项、触发器、图形、LLD、宏"打包为可复用单元。设计良好的模板应具备单一职责、可继承、可扩展、低耦合特性,是企业级 Zabbix 监控体系的基石。

模板结构:

graph TD
    A["Template App MySQL
(主模板)"] --> B["Template App MySQL Processes
(子模板)"] A --> C["Template App MySQL Connections
(子模板)"] A --> D["Template App MySQL Replication
(子模板)"] A --> E["Template App MySQL LLD
(LLD 子模板)"] F["Host: db-master-01"] -->|Link| A G["Host: db-slave-02"] -->|Link| A A -->|含| H["Items: 50"] A -->|含| I["Triggers: 20"] A -->|含| J["Graphs: 5"] A -->|含| K["LLD Rules: 3"] A -->|含| L["Macros: 5"] A -->|继承| M["Template Module Linux
(OS 基础)"]

模板设计原则:

原则说明
单一职责一个模板只负责一个应用(如 Template App MySQL、Template App Nginx)
主模板 + 子模板主模板只放公共宏、子模板链接,子模板按功能拆分
复用优先跨应用的监控(如端口、进程)放独立模板
可覆盖关键阈值用宏 {$...},主机级可覆盖
避免硬编码端口、IP、路径都需宏化
LLD 友好监控项原型使用 LLD 宏

模板继承关系:

Template App MySQL (主模板)
  ├─ Template App MySQL Processes       (子模板)
  ├─ Template App MySQL Connections     (子模板)
  ├─ Template App MySQL InnoDB          (子模板)
  └─ Template App MySQL Replication      (子模板)

应用主模板只做:
  - 链接所有子模板
  - 定义通用宏 (如 {$MYSQL.HOST}, {$MYSQL.PORT}, {$MYSQL.USER})
  - 创建 Dashboard

链接与继承的区别:

链接(Link):
  - 主机/模板添加其他模板的完整内容
  - 可链接多个

模板继承(Template nesting):
  - 模板 A "Includes other templates"
  - 实质是子模板机制
  - 方便拆分主模板

实际模板示例:

主机 db-master-01 配置:
  Linked templates:
    1. Template App MySQL (主模板)
    2. Template Module Linux (OS 基础)
  
  Macros:
    {$MYSQL.HOST} = localhost
    {$MYSQL.PORT} = 3306
    {$MYSQL.USER} = zbx_monitor
  
  → 自动应用所有子模板的 Items/Triggers/Graphs/LLD

企业级模板组织建议:

命名规范:
  Template Module <OS>           # OS 基础(CPU/Mem/Disk/Net)
  Template App <AppName>         # 应用层
  Template App <AppName> <Feature># 应用子功能
  Template Service <Service>     # 业务服务
  Template Custom <Team>         # 团队自定义

目录:
  Templates/
    OS/
    Databases/
    Middleware/
    WebServers/
    Network/
    Business/

模板版本管理:

  • 模板导出为 XML,便于 Git 追踪变更
  • 模板升级时注意宏的兼容性(旧主机可能缺少新宏)
  • 使用 Template mass update 批量更新已链接主机
12 Zabbix 宏(Macro)的类型和优先级是怎样的?

答案:

Zabbix 宏({$...})是模板与主机间"参数化"的关键机制,从全局到主机共 7 级优先级,缺省值机制让模板可独立运行,覆盖时仅在主机层修改即可。

宏类型与优先级(从低到高):

优先级宏类型作用范围示例
1(最低)内建宏固定名称的系统宏{HOST.ID}{HOST.NAME}{DATE}{TIME}
2正则表达式宏全局正则宏(web)正则告警匹配用
3用户宏(默认)全局{$SNMP_COMMUNITY}
4用户宏(模板)模板级{$THRESHOLD.CPU}
5主机宏主机级{$DB_PORT}
6触发器/Item 上下文宏仅在该 Item/Trigger 内有效自动上下文宏
7(最高)函数/Action 上下文宏表达式内联{?func(/host/key)}

内建常用宏:

{HOST.NAME}         主机名
{HOST.ID}           主机 ID
{HOST.IP}           主机 IP
{HOST.PORT}         端口
{HOST.CONN}         连接 IP:Port
{HOST.DNS}          DNS 名称
{HOST.GROUP}        主机所属组
{ITEM.LASTVALUE}    当前值
{ITEM.VALUE}        历史值
{TRIGGER.SEVERITY}  严重等级
{TRIGGER.STATUS}    状态
{EVENT.SEVERITY}    事件等级
{EVENT.TIME}        事件时间
{DATE}              当前日期
{TIME}              当前时间
{INVENTORY.<FIELD>} 资产清单字段

用户宏示例:

# 模板级宏
{$CPU.WARN}    = 70
{$CPU.CRIT}    = 90
{$MEM.WARN}    = 80
{$DISK.WARN}   = 85
{$IF.HIGHER}   = 1000000000     # 1Gbps 阈值

# Item 中使用
vfs.fs.size[/,pfree]   # 触发器
{Template App Linux: vfs.fs.size[/,pfree].last()} < {$DISK.WARN:20}

# 主机级覆盖
{$MYSQL.PORT} = 13306  # 覆盖模板默认 3306

宏的解析时机:

sequenceDiagram
    participant T as Trigger 表达式
    participant S as Server
    participant DB as 数据库

    Note over S,DB: 配置同步
    S->>DB: 读取 Host Macro 配置
    S->>DB: 读取 Template Macro 配置
    S->>S: 合并到内存缓存

    Note over T,S: 触发器评估
    T->>S: {Template App Linux: vfs.fs.size[/,pfree].last()} < {$DISK.WARN}
    S->>S: 解析宏:{$DISK.WARN} = 85
    S->>S: 代入:actual_value < 85
    S->>S: 评估结果(PROBLEM/OK)

宏的特殊用法:

# 宏的上下文:内建宏引用用户宏
{HOST.NAME} on {HOST.IP} failed: {ITEM.LASTVALUE} > {$THRESHOLD}

# 宏内嵌宏
{$ALERT.URL}  = http://alertmanager/{HOST.ID}?p={$ENV}

# 主机宏覆盖模板宏
主机级别: {$MYSQL.PORT} = 13306
模板级别: {$MYSQL.PORT} = 3306
实际生效: 13306(主机级覆盖)

# 缺省值
{$MYSQL.PORT:3306}    # 未定义时用 3306

# 用户宏在 Script/Command 中
{$SNMP_COMMUNITY} 替换到外部脚本

最佳实践:

  • 所有阈值都用宏({$DISK.WARN}、{$CPU.CRIT}),不要硬编码数字
  • 敏感信息(密码、Token)放主机宏 + 加密宏存储
  • 团队共享宏 通过全局宏,避免重复定义
  • 缺省值兜底 {$VAR:default} 防止漏配置
13 Zabbix LLD(Low-Level Discovery)的工作原理是什么?

答案:

LLD(Low-Level Discovery)是 Zabbix 自动发现机制的核心,通过预定义的发现规则(Discovery Rule)自动探测实体(网卡、磁盘、文件系统、数据库、服务),结合 Item/Trigger/Graph 原型批量创建监控项,无需手工逐一配置。

LLD 工作流程:

flowchart TD
    A["配置 LLD Rule
(key: vfs.fs.discovery)"] -->|1. 周期执行| B["Agent/Server 返回 JSON"] B --> C["JSON 解析: {#FSNAME}, {#FSTYPE}"] C --> D["匹配 Item 原型
(vfs.fs.size[{#FSNAME},pfree])"] C --> E["匹配 Trigger 原型
(... < 20 on {#FSNAME})"] C --> F["匹配 Graph 原型"] D -->|批量创建| G["实际 Item 1: vfs.fs.size[/,pfree]"] D -->|批量创建| H["实际 Item 2: vfs.fs.size[/home,pfree]"] D -->|批量创建| I["实际 Item 3: vfs.fs.size[/var,pfree]"] E --> J["实际 Trigger 1, 2, 3..."]

LLD 关键概念:

概念作用
Discovery RuleLLD 规则,定义发现逻辑,类型同 Item(Agent/SNMP/DB Monitor)
Item Prototype监控项原型,使用 LLD 宏 {#XXX},LLD 发现时实例化
Trigger Prototype触发器原型,可引用 LLD 宏
Graph Prototype图形原型,组合多个 Item 原型
Host Prototype主机原型(用于主机 LLD)
LLD Macro形如 {#FSNAME}{#IFNAME} 的动态变量

内置 LLD 规则:

# 操作系统
vfs.fs.discovery              # 文件系统
net.if.discovery              # 网卡
cpu.discovery                 # CPU 核心
memory.discovery              # 内存
system.sw.packages.discovery  # 软件包
system.disk.discovery         # 磁盘(SMART)

# 数据库(Agent 2 插件)
postgresql.discovery          # PostgreSQL 数据库/表
mysql.discovery               # MySQL 数据库/表
redis.discovery               # Redis 节点

# 中间件
docker.container.discovery    # Docker 容器

LLD 自定义发现规则:

# 自定义发现脚本(返回 JSON)
cat > /etc/zabbix/scripts/discover_services.sh <<'EOF'
#!/bin/bash
systemctl list-units --type=service --state=running --no-legend | \
  awk '{print "{\"{#SERVICE}\": \"" $1 "\"}"}' | \
  jq -s .
EOF

# 配置文件: UserParameter=service.discovery,/etc/zabbix/scripts/discover_services.sh

返回 JSON 格式:

{
  "data": [
    {"{#SERVICE}": "nginx.service", "{#PID}": "1234"},
    {"{#SERVICE}": "mysql.service", "{#PID}": "5678"},
    {"{#SERVICE}": "redis.service", "{#PID}": "9012"}
  ]
}

Item 原型示例:

Item Prototype:
  Name: Free disk space on {#FSNAME}
  Key:  vfs.fs.size[{#FSNAME},free]
  Type: Zabbix agent (active)
  Update interval: 60s

Trigger Prototype:
  Expression: {Template: vfs.fs.size[{#FSNAME},pfree].last()} < {$DISK.WARN:20}
  Name: Free disk space on {#FSNAME} is low

LLD 宏过滤:

# 发现时过滤:只发现特定类型的文件系统
LLD Rule → Filters:
  {#FSTYPE} matches (ext4|xfs|btrfs)
  {#FSNAME} does not match (/boot|^/sys|^/proc)

LLD 生命周期:

T+0s    LLD Rule 周期执行
T+0s    返回 JSON
T+0s    解析 + 过滤
T+0s    实例化所有原型
T+0s    创建实际 Item/Trigger/Graph
T+300s  下次执行(默认 1h 一次)
        - 新发现:创建新 Item
        - 已存在:跳过
        - 消失:删除旧 Item(或保留,配置项控制)

Item 不消失的设置:

LLD Rule → "Lost resources period":
  None           # 立即删除
  1h             # 1h 后未发现则删除
  Forever        # 永保留(已发现的不删除)
14 LLD 宏在监控项原型中如何高级使用?有哪些最佳实践?

答案:

LLD 宏({#MACRO})是原型实例化时的占位符。掌握宏的嵌套、组合、过滤、自定义正则等高级用法,能让模板从"够用"进化到"优雅"。

LLD 宏的来源:

来源示例说明
内建 LLD{#FSNAME}{#IFNAME}Agent/Server 内置
自定义 LLD 脚本{#DBNAME}{#TABLENAME}自行构造 JSON
多级嵌套{#FSNAME}/{#FSTYPE}JSON 返回多字段
正则提取{#IF.ALIAS} = {#IFNAME} regex二级提取

高级用法 1:多 LLD 宏组合

# 自定义发现脚本返回
{
  "data": [
    {
      "{#DB}": "users",
      "{#TABLE}": "user_profile",
      "{#ENGINE}": "InnoDB"
    }
  ]
}

# Item 原型
mysql.table.size[{#DB},{#TABLE}]

# Trigger 原型
{Template: mysql.table.size[{#DB},{#TABLE}].last()} > 1073741824

高级用法 2:LLD 宏 + 用户宏

# Item 原型中使用宏混合
vfs.fs.size[{#FSNAME},pfree]

# Trigger 阈值用用户宏
{Template: vfs.fs.size[{#FSNAME},pfree].last()} < {$DISK.WARN:20}

# 用户宏可针对 {#FSNAME} 不同设置不同阈值
# 通过主机宏 + 上下文宏

高级用法 3:自定义 LLD 宏与正则提取

# SNMP ifXTable 返回
{
  "data": [
    {
      "{#IFNAME}": "GigabitEthernet0/0/1",
      "{#IFALIAS}": "uplink-to-core",
      "{#IFSPEED}": "10000000000"
    }
  ]
}

# LLD Rule Filter: 提取 alias 中的 VLAN 信息
Filters:
  {#IFALIAS} matches .*VLAN(\d+).*  
  → 新宏 {#VLANID} = \1(正则捕获)

高级用法 4:LLD 跨模板引用

# 模板 A: Template Module Linux
LLD Rule: vfs.fs.discovery
  → Item 原型: vfs.fs.size[{#FSNAME},pfree]
  → Trigger 原型: ... < {$DISK.WARN}

# 模板 B: Template App MySQL(继承 A)
LLD Rule: mysql.databases.discovery(自定义)
  → Item 原型: mysql.db.size[{#DBNAME}]
  → Trigger 原型: ... < {$DB.SIZE.WARN}
  → 依赖 Trigger: A 模板的 vfs.fs.size[/,pfree](防止根盘满时反复告警)

高级用法 5:宏预处理与计算

# Item 原型(计算型)
Item Prototype:
  Type: Calculated
  Key:  if.util[{#IFNAME}]
  Formula: (last("net.if.in[{#IFNAME}]") + last("net.if.out[{#IFNAME}]")) * 8 / last("net.if.speed[{#IFNAME}]") * 100

# Preprocessing 步骤
Item Prototype → Preprocessing:
  1. JavaScript: return Math.round(value / 1024 / 1024)  // B → MB
  2. Regular expression: \d+

LLD 常见陷阱与最佳实践:

陷阱:
  1. LLD 周期太短(< 5min)导致 Server 压力大
  2. 过滤规则过宽,产生大量无用 Item
  3. 触发器原型硬编码阈值,未用宏
  4. Item 原型未启用 Host Inventory 资产
  5. 主机 LLD 创建的主机未关联模板

最佳实践:
  1. LLD 周期建议 1h-12h(变更不频繁的实体)
  2. 必须配置 Filter,过滤 tmpfs、/proc、/sys 等
  3. 阈值全部用用户宏,团队/主机可覆盖
  4. 命名规范: "Service: <name> on {#HOST.NAME}"
  5. Trigger 原型配合 LLD 宏 + 用户宏 + 触发器依赖
  6. 主机 LLD 自动发现主机时关联完整模板
  7. 大量 LLD 监控项时启用 "Delete lost resources"

LLD 性能影响:

LLD 创建的 Item 数 = SUM(每个 LLD Rule 发现的实体数 × 原型数)
例: 5000 主机 × 每机 5 磁盘 × 3 Item/磁盘 = 75,000 Item
    5000 主机 × 每机 3 网卡 × 5 Item/网卡 = 75,000 Item
    合计 150,000 Item

→ NVPS 估算: 150000 / 60 = 2,500 NVPS(仅 1 分钟间隔)
→ 需相应调高 StartPreprocessors、HistorySyncer
15 Zabbix 触发器表达式是怎么写的?常用函数有哪些?

答案:

触发器(Trigger)通过"表达式 + 函数 + 常量"对 Item 当前值或历史值进行评估,决定是否产生告警事件(PROBLEM/OK)。表达式语法是 Zabbix 设计的核心,灵活但有一定学习曲线。

触发器表达式语法:

{<server>:<key>.<func>(<params>)} <operator> <constant>
{host:item.key.func(params)} <op> <value>

表达式组成元素:

元素说明
<server>模板/主机名(“Template App X” 或具体主机)
<key>监控项 Key
<func>评估函数(last/avg/min/max/sum/change/diff/nodata)
<params>函数参数(时间秒数)
<operator>比较运算符(>, <, >=, <=, =, <>)
<constant>数字、字符串、宏

常用函数:

函数作用典型用法
last()最近一次采集值{vfs.fs.size[/,pfree].last()}<20
avg(N)N 秒内平均值cpu.util.avg(300)}>80
max(N)N 秒内最大值max(60)}>90
min(N)N 秒内最小值min(300)}<10
sum(N)N 秒内求和sum(60)}>1000
change()与上一次值差(差量)net.if.in.change(60)}>1000000000
diff()变化标记(0→1, 1→0)diff()}=1
nodata(N)N 秒内无数据nodata(300)}=1
time()当前时间(秒)time()}>080000(早 8 点)
date()当前日期date()}=20260101
now()当前时间(Unix 时间戳)now()-last()}>3600
regexp()正则匹配`regexp(^(ERROR
strlen()字符串长度strlen()}>1000
count(N,op,val)N 秒内满足条件的次数count(300,ge,80)}>3
forecast()预测未来值forecast(3600,1h,avg)}<10
trendavg()历史趋势平均trendavg(86400,7d)}>80

典型触发器表达式:

# 1. CPU 5 分钟内平均值 > 80%
{Template App Linux: cpu.util.avg(300)}>80

# 2. 磁盘空间小于 20% 持续 5 分钟
{Template App Linux: vfs.fs.size[/,pfree].last()}<{$DISK.WARN:20}

# 3. 端口流量突变(变化量)
{Template SNMP Interfaces: net.if.in[{#IFNAME}].change(300)}>1000000000

# 4. 5 分钟内连续 3 次超标
{Template App Linux: cpu.util.last()}>80 and
{Template App Linux: cpu.util.count(300,gt,80)}>=3

# 5. 服务宕机(无数据)
{Template App Linux: agent.ping.nodata(300)}=1

# 6. 时间窗口告警(仅工作时间)
{Template App X: queue.depth.last()}>1000 and
{Template App X: time()}>090000 and
{Template App X: time()}<180000

# 7. 多条件组合(AND/OR)
{Template App MySQL: mysql.threads.last()}>200 and
{Template App MySQL: mysql.slow_queries.rate(60)}>5

严重等级:

Not classified → Information → Warning → Average → High → Disaster
(递增严重度)

触发器可读性技巧:

# 使用宏和单位
{Host: temp.last()}>80      # 80 度
{Host: temp.last()}>$TEMP_WARN}     # 80
{Host: net.if.in.last()}>10Mbps   # 难以比较单位
→ 用宏: {Host: net.if.in.last()}>$BANDWIDTH.WARN:10485760}

# 表达式换行
{Template App Linux: cpu.util.avg(300)} > {$CPU.WARN:80} and
{Template App Linux: cpu.util.avg(300)} < 100

Hysteresis(迟滞)模式:

# Problem: > 80%, Recovery: < 70%(迟滞防抖动)
{Template: cpu.last()}>80      # 进入 PROBLEM
{Template: cpu.last()}<70      # 进入 OK

# 配合两套表达式
PROBLEM Expression: {T: cpu.last()}>80
OK Event Generation: Recovery expression: {T: cpu.last()}<70
16 触发器依赖(Dependency)如何防止告警风暴?

答案:

触发器依赖是 Zabbix 抑制告警风暴的核心机制。当上游触发器处于 PROBLEM 时,下游依赖触发器不会单独发送告警。常见模式:父级 vs 子级、节点 vs 服务、端口 vs 进程。

依赖关系示意:

graph TD
    A["HOST DOWN
(Host: agent.ping)"] --> B["Port 80 Unavailable"] A --> C["HTTP Service Unavailable"] A --> D["MySQL Connection Failed"] A --> E["Redis Connection Failed"] A --> F["Disk / Full"] F --> G["MySQL Write Failed"] F --> H["Application Error"]

依赖配置:

Trigger B: HTTP Service Unavailable
  Depends on:
    1. HOST: agent.ping (Host is unreachable)
    2. Trigger: Port 80 Unavailable (网络层)
    3. Trigger: Service nginx down (进程层)

当 HOST DOWN 时,HTTP Service 触发器不会告警
只有当 A、B、C 均 OK 时,HTTP Service 仍异常才告警

关键概念:

概念作用
依赖方向子级 trigger depends on 父级 trigger
传递性依赖会传递:A 依赖 B,B 依赖 C → A 隐含依赖 C
多父级一个 trigger 可依赖多个父级
OK 自动联动父级 OK 后,子级重新独立工作
行为父级 PROBLEM 时,子级不发送 action

典型依赖模板示例:

# 模板层依赖
Template Module Linux:
  Trigger: HOST DOWN(agent.ping)
    → 所有其他 Item 的触发器都依赖它

Template App MySQL(继承 Linux):
  Trigger: MySQL Connection Failed
    → depends on: HOST DOWN
  Trigger: MySQL Replication Lag
    → depends on: MySQL Connection Failed

Template App Nginx:
  Trigger: Nginx port 80 down
    → depends on: HOST DOWN
  Trigger: Nginx request 5xx
    → depends on: Nginx port 80 down(端口挂了不报 5xx)

配置方法:

Web UI: Trigger → Dependencies → Add parent trigger

或在 trigger 表达式中用 "Depends on":
Trigger: MySQL Connection Failed
  Dependencies:
    - Trigger: {HOST.NAME}: agent.ping.nodata(300)=1
    - Trigger: {HOST.NAME}: icmppingloss.max(60)=100

依赖 vs Action Conditions:

机制作用时机
Trigger Dependency抑制依赖 trigger 产生事件Trigger 评估层
Action Conditions过滤 action 是否发送Action 执行层
Tag-based filtering抑制相同 tag 的 actionAction 发送层

最佳实践:

1. 主机层依赖(HOST DOWN)
   - 主机不在线时,所有服务级 trigger 都不告警
   - 在模板中配置:所有应用 trigger depends on HOST

2. 服务层依赖(Service: 端口 → 进程 → 业务)
   - 端口挂了不报业务异常
   - 进程挂了不报 HTTP 5xx

3. 节点依赖(Node)
   - 数据库主从:主库挂了从库告警升级
   - K8s 节点:节点 NotReady → Pod 异常

4. 避免循环依赖
   - A → B → A 会导致评估异常

告警风暴的真实场景:

场景: 网络交换机故障
1. 交换机挂 → 50 台服务器网络不通
2. 每台服务器触发:agent.ping fail、service down、磁盘读不到、连接超时...
3. 每台机器发 30+ 告警 × 50 台 = 1500 条告警轰炸
4. 值班人员崩溃

→ 依赖配置后:仅 1 条 "交换机 X 不可达" 告警
17 Zabbix 告警升级(Escalation)流程如何设计?

答案:

告警升级(Escalation)是 Action 引擎的核心能力,按照"步骤(Step)“和"条件"在指定时间窗内逐级发送告警、通知更高级别的人、执行远程命令。设计良好的升级流程能在告警处理的"早期"和"晚期"采取不同动作。

告警升级原理:

sequenceDiagram
    participant T as Trigger
    participant A as Action 引擎
    participant S1 as 一线运维
    participant S2 as 二线/DBA
    participant S3 as 主管/CTO
    participant RC as 远程命令

    T->>A: PROBLEM 事件
    A->>S1: Step 1: 邮件 (立即)
    Note over A: 等待 10 分钟
    A->>S1: Step 2: 短信 (持续 PROBLEM)
    Note over A: 等待 10 分钟
    A->>S2: Step 3: 电话 (持续 PROBLEM)
    Note over A: 等待 20 分钟
    A->>S3: Step 4: 升级到主管 (持续 PROBLEM)
    Note over A: 等待 30 分钟
    A->>RC: Step 5: 自动重启服务 (持续 PROBLEM)
    T->>A: 恢复 OK
    A->>S1: 恢复通知(邮件)

Action 关键概念:

概念说明
Action告警动作主体,绑定 trigger/host/discovery 等
Operations操作步骤(发送/远程命令),可多个
Steps步骤(1-10),可分批/分时
Step duration每步持续时间
Conditions触发条件(trigger severity/host group/tag)
Send to user group收件人(用户组)
Send via媒介类型(Email/SMS/Webhook/Script)
Default subject/message告警标题与内容模板

Action 步骤设计:

Operations:
  Step 1: 立即执行
    - Send message: Email to group "ops-l1" (message: ${TRIGGER.NAME} on {HOST.NAME})
  
  Step 2: 10 分钟后(PROBLEM 持续)
    - Send message: SMS to group "ops-l1" (短信模板)
    - Delay between operations: 600s
  
  Step 3: 30 分钟后(仍 PROBLEM)
    - Send message: Email to group "ops-l2-dba" (CC 二线)
    - Delay: 1200s
  
  Step 4: 1 小时后
    - Run remote command: /usr/local/bin/restart.sh on {HOST.IP}
    - Send message: WeChat webhook to channel #sre-alert
  
  Step 5: 4 小时后
    - Send message: Email to group "ops-leader"
    - Run script: 自动化恢复流程

Action 步骤设置:

Step from / Step to:  步骤范围
  1 → 1:  仅步骤 1(独立执行)
  1 → 9:  步骤 1-9(连续执行)

Step duration:  单步持续时间(默认 0 = 立即执行)
  Step 1: 0 (立即)
  Step 2: 600 (10min 后)
  Step 3: 1800 (30min 后)
  ...

Operation type:
  - Send message
  - Run remote command
  - Add host to group
  - Remove host from group
  - Add to maintenance
  - Notify all involved

消息模板示例:

# 告警标题
[Zabbix] {TRIGGER.SEVERITY}: {TRIGGER.NAME} on {HOST.NAME}

# 告警内容
Trigger:    {TRIGGER.NAME}
Host:       {HOST.NAME} ({HOST.IP})
Severity:   {TRIGGER.SEVERITY}
Time:       {EVENT.DATE} {EVENT.TIME}
Value:      {ITEM.LASTVALUE}
Threshold:  {TRIGGER.EXPRESSION}
Status:     {TRIGGER.STATUS}

Event ID:   {EVENT.ID}
Ack URL:    http://zabbix.example.com/tr_events.php?triggerid={TRIGGER.ID}

远程命令(Remote Command):

Operation: Run remote command on {HOST.IP}
  Type: Custom script
  Execute on: Zabbix agent
  Commands:
    sudo /usr/local/bin/restart_service.sh {HOST.NAME}

# Zabbix Server 配置
EnableRemoteCommands=1
# Zabbix Agent 端允许远程命令
AllowKey=system.run[*]

# 危险命令禁用
DenyKey=system.run[*]
DenyKey=system.run[*]

告警升级的常见设计模式:

模式步骤
一线+二线升级Step 1-2: 一线;Step 3-4: 二线
分时段升级Step 1-2: 工作时间;Step 3+: 非工作时间直接升级
按严重度分流Disaster → 5 分钟升级;Warning → 30 分钟升级
自动恢复Step 5: 自动重启 + 人工跟进
PagerDuty 集成Step 4: 集成外部 on-call 系统

Action 条件过滤:

Conditions(Action 触发条件):
  - Trigger severity >= High
  - Host group = "Production"
  - Trigger name matches "MySQL"
  - Time period: weekday 09:00-18:00
  - Tag: Service = "payment"
18 标签(Tag)在告警管理中如何应用?Tag-based filtering 与抑制机制是什么?

答案:

Tag 是 Zabbix 5.0+ 引入的关键能力,给 Trigger/Host/Template/Item 打标签,结合 Action Conditions 实现"按业务、按服务、按团队"的精细化告警路由和抑制。

Tag 体系架构:

graph LR
    A["Trigger
tag: Service=payment
tag: Severity=critical"] -->|1. 事件携带 tags| B["Event"] B -->|2. Action Conditions 匹配| C["Action 1: 支付团队"] B -->|2. Action Conditions 匹配| D["Action 2: DBA 团队"] B -->|2. Action Conditions 匹配| E["Action 3: 基础设施"] F["Inheritance:
Template tag → Host tag
Host tag → Item/Trigger tag"] -.继承.-> A

Tag 关键能力:

能力作用
Tag 分类Trigger/Host/Template/Item 可独立打 tag
Tag 继承Template tag 继承到 Host,Host tag 继承到 Item/Trigger
Action 过滤按 tag 值路由到不同用户组/媒介
Tag 抑制同 tag 已告警时不再重复发送
Event 携带告警事件携带 tag,便于溯源
宏中使用{EVENT.SERVICE} 等 tag 宏在通知中可用

Tag 类型与作用范围:

Tag 作用域:
  Template tag         # 模板层,所有链接主机继承
  Host tag              # 主机层,可覆盖模板
  Trigger tag           # 触发器层,最具体
  Item tag              # 监控项层(与 LLD 配合)

Tag 命名建议:
  Service:  payment, user, order
  Env:      prod, staging, dev
  Owner:    team-a, team-b
  Component: db, cache, queue
  Severity: critical, warning, info

Action 条件:Tag 路由:

Action: 支付业务告警
  Conditions:
    A: Trigger severity >= High
    B: Tag "Service" matches "payment"
    C: Host group = "Production"
  Operations:
    Step 1: Send Email to group "payment-team"
    Step 2: SMS to "payment-oncall"
    Step 3: Phone to "payment-lead"

Action: 数据库告警
  Conditions:
    A: Trigger severity >= Warning
    B: Tag "Component" matches "db"
  Operations:
    Step 1: Send to "dba-team"

Action: 基础设施告警
  Conditions:
    A: Tag "Component" matches "infra|network|storage"
  Operations:
    Step 1: Send to "infra-team"

Tag-based 抑制:

场景: 主机宕机后,MySQL、Nginx、Redis 都会告警

Action: MySQL Down
  Conditions:
    B: Tag "Service" = "mysql"
  Operations:
    Step 1: Send to dba-team

Action: 抑制规则
  Conditions:
    A: Tag "Host" = "{HOST.NAME}" AND Tag "Service" matches ".*"
    B: Trigger severity <= Average
  Operations:
    None (匹配此规则的 trigger 不发送)

→ 当 MySQL 主机已发送 PROBLEM 告警,
  同主机的其他子项告警被抑制,避免风暴

实际业务标签设计:

# 模板层
Template App MySQL:
  Host tag: Service=mysql, Component=database
  Trigger tag:  Severity=critical, Type=availability

# 主机层覆盖
Host: order-db-master-01:
  Tag: Env=prod, Owner=order-team, Business=order-service
  Tag: SLA=critical  # 覆盖

# Trigger 层细化
Trigger: MySQL Replication Lag
  Tag: SLA=critical, Impact=write-failover

在通知中引用 Tag:

# 告警内容模板
Host: {HOST.NAME} (IP: {HOST.IP})
Service: {EVENT.SERVICE}        # Tag "Service"
Environment: {EVENT.ENV}        # Tag "Env"
Owner: {EVENT.OWNER}            # Tag "Owner"
Component: {EVENT.COMPONENT}    # Tag "Component"

# 告警 URL
https://alert.example.com/ack?event={EVENT.ID}&service={EVENT.SERVICE}

Tag vs User Macro 的区别:

维度TagUser Macro
用途标识与路由参数化阈值/配置
作用Action 条件过滤Item/Trigger 内部引用
继承可继承可覆盖可继承可覆盖
运行时事件携带,可被表达式/通知使用仅在配置中替换
典型场景“Service=payment 路由到支付团队”“{$DISK.WARN:20} 阈值可调”
19 Zabbix Proxy 的工作原理和适用场景是什么?

答案:

Zabbix Proxy 是 Server 的"区域代理",是分布式监控的基石。Proxy 部署在被监控区域,独立完成本区域内采集、触发器评估、数据缓冲,然后周期性批量上报给 Server,缓解 Server 采集压力和网络隔离限制。

Proxy 架构:

graph TD
    subgraph "IDC 北京"
        A["Zabbix Proxy 北京"]
        B["区域设备
Agent/SNMP/IPMI"] C["网络设备
SNMP"] A -->|采集| B A -->|采集| C end subgraph "IDC 上海" D["Zabbix Proxy 上海"] E["区域设备"] D -->|采集| E end subgraph "核心机房" F["Zabbix Server"] G[("数据库")] F -->|读/写| G end A -->|Proxy 数据上报| F D -->|Proxy 数据上报| F

Proxy 核心能力:

能力说明
本地采集Proxy 负责该区域所有 Item 的采集(Agent/SNMP/IPMI/Trapper)
本地触发器评估Proxy 本地评估触发器,Buffer 超限才上报 Server
数据缓冲网络中断时本地缓存数据(DB 文件),恢复后批量上传
配置同步与 Server 同步模板、Item 配置(定期拉取)
自动发现Proxy 支持所有发现类型(LLD、网络发现)
告警冗余Proxy 异常时本地数据不丢失(最多保留 proxy Buffer 时间)

Proxy 两种工作模式:

模式连接方向数据上报防火墙要求
主动模式(推荐)Proxy 主动连接 Server 10051周期上报缓冲数据仅 Proxy 出站可达 Server
被动模式Server 主动连接 Proxy 10051Server 拉取数据Server 需可达 Proxy
# Proxy 配置(主动模式,推荐)
ProxyMode=0                     # 0: 主动, 1: 被动
Server=<Server IP>              # Server 地址(主动模式用)
Port=10051
Hostname=proxy-beijing
BufferSize=4096                 # 4MB 数据缓冲(越大越抗网络抖动)
ProxyLocalBuffer=0              # 本地缓冲 0=disable
ProxyOfflineBuffer=1            # 离线缓冲 1=enable(断网时保留数据)

# Proxy 配置(被动模式)
ProxyMode=1
Server=<Server IP>
Port=10051
Hostname=proxy-beijing

Proxy 数据缓冲机制:

正常状态:
  Proxy 实时采集 → 写入本地 Buffer → 批量发送 Server

网络中断:
  Proxy 实时采集 → 写入本地 Buffer → Buffer 满 → 覆盖旧的历史(可配置)

网络恢复:
  Proxy 检测到 Server 可达 → 批量发送缓冲数据 → 触发 Server 处理
  → 历史数据补写(趋势趋势图不受影响)
  → 告警评估由 Server 同步后触发

→ BufferSize 越大,可承受的网络中断时间越长
→ Proxy 内存缓冲不影响 Agent 端的实时采集

Proxy 持久化数据:

Proxy 存储文件:
  /tmp/zabbix_proxy.db   # SQLite
  存储: 配置缓存、历史缓冲、值缓存、队列、趋势

重要:
  - Proxy 本身的元数据文件(SQLite)不是最终数据
  - Proxy 重启后重置 SQLite,不影响 Server 端已同步数据
  - Proxy 离线超过保留期后,Server 触发 Trigger "Zabbix proxy is not available"

Proxy vs Agent 对比:

维度ProxyAgent
职能数据汇聚 + 代理采集单机指标采集
规模数百到数千 Host单机到数十 Host(被 Proxy/Server 管理)
触发器本地评估不负责评估
部署独立服务器每台被监控机
配置从 Server 同步Server/Proxy 下发配置
数据流Proxy → Server → DBProxy/Server → 值缓存 → DB
OS 要求同 Server(支持 Linux/Unix)支持 Linux/Windows

最佳实践:

Proxy 部署场景:
  ✔ 跨机房/跨 IDC(WAN 环境)
  ✔ 大规模环境(单 Server > 10k Host 时拆分)
  ✔ 网络隔离区域(DMZ、办公网)
  ✔ 远程分支(站点/门店)
  ✔ 需要本地触发器响应的场景

Proxy 配置建议:
  1. 每 Proxy 管理 ≤ 2000 Host(经验值)
  2. Proxy 与 Server 间带宽 ≥ 10 Mbps(批量上报)
  3. 主动模式优先(防火墙友好)
  4. BufferSize ≥ 4MB(容忍网络抖动)
  5. Proxy 配置一致性(与 Server 同版本优先)
20 Proxy 主动模式与被动模式有什么区别?各适用于什么场景?

答案:

Proxy 主动/被动模式的区分点在于"谁发起连接":主动模式由 Proxy 发起,适合网络隔离区域(仅 Proxy 出站可达 Server);被动模式由 Server 主动轮询 Proxy,适合局域网场景(Server 可直连 Proxy)。

连接方向对比:

sequenceDiagram
    participant S as Zabbix Server
    participant P as Zabbix Proxy
    participant A as Agent

    rect rgb(240, 255, 240)
    Note over S,P: 主动模式(推荐)
    S->>S: 启动
    P->>S: Proxy 注册 (hello)
    S-->>P: 返回配置(host/template/item)
    loop 周期上报
        P->>S: 批量数据(values)
        S-->>P: ACK
    end
    end

    rect rgb(255, 240, 240)
    Note over S,P: 被动模式
    S->>P: 拉取数据
    P-->>S: 返回缓冲数据
    loop
        S->>P: configuration sync
        P-->>S: 确认
    end
    end

    P->>A: 本地采集
    A-->>P: 返回数据

对比表:

维度主动模式被动模式
连接方向Proxy 主动连接 ServerServer 主动连接 Proxy
Server 端口Proxy 出站 10051Proxy 监听 10051
防火墙代理端无需入站Server 需入站 Proxy
配置ProxyMode=0 + Server 字段ProxyMode=1
中断恢复Proxy 感知中断,本地缓冲Server 感知 Proxy 不可达
可观测性Proxy 内部监控项更完整依赖 Server 侧队列监控
流量控制Proxy 控制上传速率Server 控制拉取频率
推荐跨 IDC / 临域网 / 远程站点同机房 / 同 VPC
数据延迟受上报周期控制取决于 Server 拉取频率

Proxy 主动模式优势:

1. 网络隔离友好:仅 Proxy 出站发起连接,Server 不需要反向可达
2. 本地缓冲:Proxy 主导数据流,断网缓冲数据不丢失
3. 自我监控:Proxy 提供内部监控项(zbx_proxy[queue,pending])
4. 批量策略:Proxy 按批次发送,Server 端负载可控
5. 自动重连:Proxy 持续重试,Server 恢复后自动续传

选择策略:

Proxy 强制主动模式:
  ✔ 跨防火墙(Proxy 在 DMZ,Server 在内网)
  ✔ 分支机构(Proxy 在外地,Server 在公司)
  ✔ Server 无法直接访问 Proxy(NAT、VPN)
  ✔ 需要 Proxy 独立处理网络中断

Proxy 被动模式:
  ✔ Proxy 与 Server 同局域网
  ✔ 需要 Server 主动控制采集周期
  ✔ 需要 Server 侧精准监控 Proxy 状态
  ✔ 低延迟要求(Server 高频率拉取)

Proxy 三种角色对比:

角色主要用途数据上报
Zabbix Proxy通用场景,区域代理 + 数据缓冲周期性批量上报 Server
Zabbix Server + ProxyHA 场景,failover双节点互备
Zabbix Satelline多级 Proxy 级联(很少用)级联上报

配置调优:

# Proxy 块参数
StartPollers=40
StartTrappers=10
HeartbeatFrequency=60           # 心跳周期(秒)
ConfigFrequency=180              # 配置同步周期(秒)
DataSenderFrequency=10           # 数据发送周期(秒)

# 数据缓冲
BufferSize=4096
TrapperTimeout=30

# 主动模式专属
Port=10051                       # 监听端口(日常用不上)
21 Zabbix 6.0+ 原生 HA 集群(High Availability Cluster)的主要机制是什么?

答案:

Zabbix 6.0 LTS 引入原生 HA(High Availability Cluster)支持,多个 Server 节点组成集群,Active-Passive 工作模式,心跳检测 + 数据库级选主,切换时间可达秒级,比传统的 DRBD/Keepalived 方案更简洁可靠。

HA 集群架构:

graph TD
    subgraph "Zabbix HA Cluster"
        A["Server Node 1 (Active)
主节点"] -->|读写| C[(数据库)] B["Server Node 2 (Standby)
备用节点"] -->|Standby 不处理业务/不写| C D["Server Node 3 (Standby)
备用节点"] -->|Standby 不处理业务/不写| C end C --> E["Web 前端
PHP (可多实例)"] F["Agent / Proxy"] -->|连接 Active 节点| A F -.->|掉线重连| B

HA 核心机制:

机制说明
集群成员每个 Server 节点有 name 和 address,注册到数据库 ha_node
选主数据库级(MySQL/PostgreSQL),基于 ha_node 表的心跳时间戳
心跳每节点周期写入 ha_node.lastaccess(默认 5s)
Active 切换Standby 节点检测到 Active 心跳超时 → 自己升级为 Active
故障检测窗口HAFailoverDelay(默认 5s,连续 3 个心跳缺失)
Proxy/Agent 重连自动检测新的 Active 节点并重连(无需配置)
Web 前端可同时连接集群,自动路由到当前 Active(api.ha_nodename)
无 Load BalancerServer 端完成选主,无需外部 LB(但 LB 可优化前端)

HA 节点状态:

ACTIVE       # 当前主节点,正在处理业务(采集/评估/告警)
STANDBY      # 备用节点,实时同步心跳,随时准备接管
STOPPED      # 节点已停止(手动维护/故障)
ERROR        # 节点异常(配置错误、数据库连接失败)

HA 配置步骤:

# 1. 所有 Server 节点配置相同的数据库连接
DBHost=192.168.1.10
DBName=zabbix
DBUser=zabbix
DBPassword=xxxx

# 2. 配置 HA 节点名称和地址
HANodeName=server-01.example.com
HANodeAddress=192.168.1.101:10051

# 3. 启动多个 Server 实例
systemctl start zabbix-server@server-01
systemctl start zabbix-server@server-02
systemctl start zabbix-server@server-03

HA 节点数据流:

Active 节点:
  - 采集(poller/trapper/snmp/ipmi/jmx)
  - 预处理(preprocessor)
  - 触发器评估(trigger engine)
  - 告警动作(alerter/escalator)
  - 数据库同步(configuration syncer / history syncer)
  - 管理 LLD、Housekeeper

Standby 节点:
  - 不做任何采集/评估/告警
  - 仅做心跳检测 + 数据库连接保活
  - 可选开启 Web 前端但不处理采集业务
  - 所有进程无负载(除心跳进程外基本空闲)

故障切换流程:

T+0s    Active 节点宕机(进程 crash / 服务器断电)
T+5s    Standby 节点检测到 lastaccess 超时(HAFailoverDelay=5)
T+5s    Standby 节点检查其他节点
T+5s    Standby 节点升为 Active
T+5s    开始接收 Agent/Proxy 连接
T+5~10s Agent/Proxy 重连到新 Active 节点

→ 切换时间: 5-15s(取决于 HAFailoverDelay 和网络延迟)

HA 监控与运维:

# 查看 HA 集群状态(数据库级)
mysql -e "SELECT nodeid, name, address, status, lastaccess, ha_nodename FROM ha_node;"

# 内部监控项
zabbix_get -s 127.0.0.1 -k zabbix[ha,status]
# → 'active' | 'standby'

zabbix_get -s 127.0.0.1 -k zabbix[ha,lastaccess]
# → 当前时间戳

zabbix_get -s 127.0.0.1 -k zabbix[ha,nodename]
# → server-01.example.com

HA 与 Proxy 的配合:

场景: HA + Proxy 混合架构
  Proxy 连接 Server HA 集群时,无需配置多个 Server IP
  Proxy 配置:
    Server=<active-server-ip>         # 推荐配置单个 Active 地址
    或用: Proxy 检测到连接的 Server 为 Standby → 自动重试

  更好的做法:
    Proxy 配置同时指定两个 Server 地址:
    Server=192.168.1.101,192.168.1.102
    但注意 Proxy 优先连接第一个可达的(不智能)

原生 HA vs 传统方案的对比:

维度原生 HA(6.0+)DRBD + Keepalived
复杂度低(配置 3 个参数)高(DRBD 同步 + VIP 切换 + 共享存储)
切换时间5-15s30-60s(DRBD promotion)
数据一致性数据库本身容灾DRBD 同步延迟可能丢数据
存储无共享存储要求需要 DRBD 共享块设备
运维Server/Web 单体化存储/Server/Web 三层分离
失败点少了存储层(数据库本身)存储层单点引入更多故障场景
回退简单(停止备用节点)复杂(DRBD 同步状态需修复)
22 Zabbix 高可用的传统方案和非原生方案还有哪些?

答案:

在 Zabbix 6.0 原生 HA 出现之前(及 6.0 之后仍有遗留场景),业界使用 DRBD、Keepalived、数据库主从、多 Proxy 等传统方式实现高可用。部分方案仍适用于已有基础设施或补全原生 HA 未覆盖的层。

传统 HA 方案对比:

方案组件切换时间复杂度适用版本
DRBD + Keepalived共享存储 + VIP30-60s4.x-6.x 通用
Active-Standby + 共享存储NFS/GFS260-120s所有版本
多 Proxy 并行数据叠加-所有版本
数据库 HA + Server 双机MySQL MGR + Keepalived10-30s所有版本
6.0+ 原生 HAServer 集群5-15s6.0+

方案 1:DRBD + Keepalived(传统方案)

架构:
  Server_Active ← VIP: 192.168.1.10 → Agent/Proxy
      │                                   │
      │ DRBD sync                         │
  Server_Standby ← VIP 漂移              │
      │                                   │
  [DRBD Primary/Secondary]
  [MySQL (独立节点)]

流程:
  1. 两台 Server 共享一个 DRBD 块设备(/dev/drbd0)
  2. DRBD Primary 挂载后启动 zabbix_server
  3. Keepalived 维护 VIP(192.168.1.10)
  4. 主节点故障 → DRBD Secondary→Primary → Keepalived VIP 漂移 → 启动 Server

缺点:
  - DRBD 同步延迟(async vs sync 模式)
  - 存储层单点故障(DRBD 本身)
  - 切换期间数据丢失(同步模式下仍可能)

方案 2:MS SQL Server AG / MySQL InnoDB Cluster

架构:
  Zabbix Server A → MySQL MGR Primary
  Zabbix Server B → MySQL MGR Secondary(Read-Only)
  
  VIP / DNS:
    Server A 关联 VIP
    VIP 切换时 B 接管
  
流程:
  1. MySQL MGR 提供高可用数据库
  2. Server A 正常连接数据库 Primary
  3. Server A 故障 → VIP 漂移到 B
  4. Server B 连接 MySQL MGR Primary(自动切换读/写)

优势:
  - 数据库自动容灾(MGR 自动选主)
  - Server 层轻量(无共享存储)
  - MySQL MGR 本身是 Zabbix 推荐的方案之一

方案 3:Zabbix Proxy + 多 Proxy 分担

架构:
  多 Proxy 并行(非 HA,而是负载分担):
  Proxy_A (Beijing) — 10,000 Host
  Proxy_B (Shanghai) — 8,000 Host
  Proxy_C (Guangzhou) — 5,000 Host
  Proxy_D (Hangzhou) — 3,000 Host
  
HA Proxy:
  双 Proxy 同区域:
  Proxy_A1 (Active) — Agent/SNMP 采集
  Proxy_A2 (Standby) — 本地区域备用
  → Agent 配置同时指定两个 Proxy

此方案不是 Server HA,而是 Proxy 层级的高可用
可降低 Server 单点故障风险

方案 4:6.0 原生 HA + 数据库 HA(推荐)

推荐架构:
  Zabbix HA Cluster (3 节点)
    ├─ Server-A (Active)
    ├─ Server-B (Standby)
    └─ Server-C (Standby)
  
  MySQL InnoDB Cluster / PostgreSQL Patroni
  ├─ DB-Primary (Read/Write)
  ├─ DB-Replica1 (Read-Only)
  └─ DB-Replica2 (Read-Only)
  
  Web Frontend × N (可多实例)
  
  Proxy × N (按区域)
  
优势:
  - Server 层 5-15s 自动切换
  - 数据库层自动故障转移
  - Web 层无状态,前端可任意分布
  - 无共享存储、无 DRBD 引入的单点

HA 设计决策树:

是否需要 Server HA?
├─ Zabbix 6.0+ → 原生 HA(推荐)
└─ Zabbix < 6.0
   ├─ 已有 DRBD 基础设施 → DRBD + Keepalived
   └─ 无 DRBD
      ├─ 可升级 → 升级 6.0+ 原生 HA
      └─ 不可升级
         ├─ 数据库已 HA → 双 Server + VIP + 数据库切换
         └─ 数据库无 HA → Proxy 分担 + 单 Server 容错
23 Zabbix 数据库选型:MySQL、PostgreSQL 与 TimescaleDB 各自优缺点?

答案:

Zabbix 从 1.x 开始支持 MySQL,5.0+ 正式支持 TimescaleDB(PostgreSQL 扩展),6.0 LTS 推荐使用 TimescaleDB。三种数据库在架构、性能、运维复杂度上有明显差异。

数据库对比:

维度MySQLPostgreSQLTimescaleDB
架构传统关系型传统关系型PostgreSQL + 时序表扩展
历史数据存储history 表行式行式,支持分区超表(Hypertable)自动分区
自动分区需手动(Partitioning by RANGE)需 pg_partman 插件内置 Chunk 自动分区
压缩率无原生存放压缩TOAST 压缩列式原生压缩(5x-10x)
趋势/历史保留需手工清理(Housekeeper)同 MySQLInterval 自定义 + 自动压缩
查询性能(历史)行式,分页查询慢好(支持并行查询)极好(Chunk 裁剪 + 压缩)
NVPS(推荐)≤ 3,000(经验值)≤ 5,00010,000-100,000+
部署复杂度中高(需配置超表 + 压缩策略)
运维成本中(压缩管理)
社区/文档最广泛成熟Zabbix 官方推荐 6.0+

TimescaleDB 优势(Zabbix 6.0+ 推荐):

TimescaleDB 关键能力:
  1. 自动分区(Chunk)
     CREATE TABLE history (…) → SELECT create_hypertable('history','clock')
     → 按天/小时/分钟自动分 Chunk,不需要手工维护分区

  2. 原生压缩
     空间压缩: 5-15x(housekeeping 前)
     时间压缩: 自动(job 定时运行)
     再分区 + 按时间聚合 → 查询仍高效

  3. 连续聚合
     类似物化视图 + 自动刷新
     大幅提升长周期趋势图/报表性能

  4. 列式存储(超表)
     Chunk 内部按列存储(压缩友好)
     历史查询只需扫描相关列

TimescaleDB 配置示例:

-- Zabbix 数据库初始化(PostgreSQL + TimescaleDB)
-- create database
CREATE DATABASE zabbix WITH TEMPLATE template0;

-- 启用 TimescaleDB 扩展
CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE;

-- 历史表转为超表
SELECT create_hypertable('history', 'clock',
    chunk_time_interval => 86400);        -- 1 天一个 Chunk
SELECT create_hypertable('history_uint', 'clock',
    chunk_time_interval => 86400);
SELECT create_hypertable('history_str', 'clock',
    chunk_time_interval => 86400);
SELECT create_hypertable('history_log', 'clock',
    chunk_time_interval => 86400);
SELECT create_hypertable('history_text', 'clock',
    chunk_time_interval => 86400);
SELECT create_hypertable('trends', 'clock',
    chunk_time_interval => 86400);
SELECT create_hypertable('trends_uint', 'clock',
    chunk_time_interval => 86400);

-- 压缩策略(存储优化)
SELECT add_compression_policy('history',  INTERVAL '7 days');
SELECT add_compression_policy('history_uint', INTERVAL '7 days');
SELECT add_compression_policy('history_str',  INTERVAL '7 days');
SELECT add_compression_policy('history_log',  INTERVAL '7 days');
SELECT add_compression_policy('history_text', INTERVAL '7 days');

MySQL 分区配置(手动维护):

-- MySQL 分区(Zabbix 4.x-5.x 常用)
ALTER TABLE `history`
  PARTITION BY RANGE (clock) (
    PARTITION p202601 VALUES LESS THAN (UNIX_TIMESTAMP('2026-02-01 00:00:00')),
    PARTITION p202602 VALUES LESS THAN (UNIX_TIMESTAMP('2026-03-01 00:00:00')),
    PARTITION p202603 VALUES LESS THAN (UNIX_TIMESTAMP('2026-04-01 00:00:00')),
    PARTITION p202604 VALUES LESS THAN (UNIX_TIMESTAMP('2026-05-01 00:00:00')),
    PARTITION p202605 VALUES LESS THAN (UNIX_TIMESTAMP('2026-06-01 00:00:00')),
    PARTITION p202606 VALUES LESS THAN (UNIX_TIMESTAMP('2026-07-01 00:00:00')),
    PARTITION p_future VALUES LESS THAN MAXVALUE
  );

数据库选型建议:

场景 → 推荐
  ← 3,000 NVPS   → MySQL(够用且运维最轻)
  3k-10k NVPS    → PostgreSQL(性能强于 MySQL)
  ≥ 10k NVPS     → TimescaleDB(压缩 + Chunk 自动分区)
  NVPS 极高      → TimescaleDB + 多 Proxy 分担采集

增量迁移:
  MySQL 可在线迁移到 TimescaleDB(pgloader 工具有支持)
  迁移后 Housekeeper 策略改为压缩策略,磁盘节省 5-10x
24 Housekeeper(数据清理)的工作原理是什么?如何调优?

答案:

Housekeeper 是 Zabbix Server 的内置进程,负责删除过期的历史数据、事件、审计日志、Action 日志等,防止数据库无限膨胀。不调优的 Housekeeper 在大规模场景下可能成为瓶颈,甚至拖垮数据库写入性能。

Housekeeper 工作流程:

flowchart LR
    A["定时任务
(每小时)"] --> B["检查 Item History 保留期"] A --> C["检查 Event 保留期"] A --> D["检查 Audit/Action 保留期"] B --> E["DELETE FROM history WHERE clock < :time"] C --> F["DELETE FROM events WHERE eventid < :id"] D --> G["DELETE FROM audit WHERE clock < :time"] E --> H[(数据库: history 空间释放)] F --> I[(events 表收缩)] G --> J[(audit 表压缩)]

保留期配置:

# Web UI → Administration → General → Housekeeper
Housekeeping frequency:        1        (小时)
Trigger data storage period:  365
Internal events:              365
Network discovery events:     30
Auto-registration events:     30

# Item 级保留期(每个 Item 可单独设置)
Item:
  History storage period: 7d-90d
  Trends storage period:  365d

# 全局保留期(Item 未设置时使用)
History retention:         14d
Trends retention:          365d

Housekeeper 性能影响:

问题: Housekeeper 在大表上执行 DELETE 大量数据时:
  - 表锁定/行锁定(MySQL InnoDB 需小心死锁)
  - INSERT 被阻塞(写入 history 表会锁等待)
  - 触发器评估延迟(历史数据被锁定)
  - Event 表 DELETE 影响 event 处理

建议:
  - MySQL: 禁用内置 Housekeeper,改用外部 Cron 分区 Drop/Truncate
  - PostgreSQL: 可启用内置(并行 DELETE 较友好)
  - TimescaleDB: 内置压缩 + Chunk drop(压缩后数据自动过期)

优化方案 1:MySQL 分区 Drop(推荐)

-- 每月 1 日凌晨  将过期分区直接 DROP(极快)
-- 代替 DELETE,秒级完成(DROP TABLE 是 DDL,无锁)

ALTER TABLE `history` DROP PARTITION p20260401;
ALTER TABLE `history` DROP PARTITION p20260402;
-- ...

-- Zabbix 配置:禁用内置 Housekeeper 的历史表删除
HousekeepingFrequency=0            # 关闭内置 Housekeeper

优化方案 2:TimescaleDB 压缩 + 过期策略

-- TimescaleDB 策略:保留 30 天后自动删除 Chunk
SELECT add_retention_policy('history', INTERVAL '30 days');
SELECT add_retention_policy('history_uint', INTERVAL '30 days');

-- 配合压缩:7 天后自动压缩
SELECT add_compression_policy('history', INTERVAL '7 days');

-- 最佳实践:压缩 7d + 保留 30d → 磁盘节省 80%

优化方案 3:外部脚本(通用)

#!/bin/bash
# /usr/local/bin/zbx_housekeeper.sh
# cron: 0 2 * * * /usr/local/bin/zbx_housekeeper.sh

DB_USER=zabbix
DB_PASS=xxxx
DB_NAME=zabbix

# 删除 90 天前的 history_uint
echo "DELETE FROM history_uint WHERE clock < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 90 DAY)) LIMIT 100000;" | \
  mysql -u$DB_USER -p$DB_PASS $DB_NAME &

Housekeeper 监控项:

# 内部监控项检查 Housekeeper 状态
zabbix_get -s 127.0.0.1 -k zabbix[housekeeping,start_time]      # 上次清理时间
zabbix_get -s 127.0.0.1 -k zabbix[housekeeping,count]            # 本次清理行数
zabbix_get -s 127.0.0.1 -k zabbix[housekeeping,duration]         # 清理耗时(ms)
zabbix_get -s 127.0.0.1 -k zabbix[process,housekeeper,avg,busy] # Housekeeper 负载
25 Zabbix 性能瓶颈如何定位?NVPS/TPS 估算与配置调优方法?

答案:

Zabbix 性能瓶颈最常用的指标是 NVPS(New Values Per Second,每秒新值数),也称为 TPS(Transactions Per Second)。定位瓶颈需遵循"Cache → DB → Poller → Preprocessor"的顺序排查。

NVPS 估算:

NVPS = SUM( 所有 Item 数 / 采集间隔)

例:
  Item 类型            Item 数    采集间隔(s)    NVPS
  Internet/Agent         800          60          13.3
  SNMP                    200         300         0.7
  Trapper                  50           -         10
  Active Agent           1200          60          20.0
  LLD                       5        3600         0.0
  Web Scenario             10         120          0.08
  ------
  总计:                  2265 Item                ~44 NVPS

  → 一台 Server 可承载数千 NVPS(经验值 2,000-10,000)
  → >10,000 NVPS 需 Proxy 分发和 TimescaleDB

瓶颈排查流程:

flowchart TD
    A["发现延迟/队列堆积"] --> B["检查 zabbix[queue]"]
    B --> C{"队列值 > 10?"}
    C -- No --> K["检查其他进程
db_syncer/housekeeper"] C -- Yes --> D{"poller busy > 75%?"} D -- Yes --> E["增加 StartPollers"] D -- No --> F{"trapper busy > 75%?"} F -- Yes --> G["增加 StartTrappers"] F -- No --> H{"history_syncer busy > 75%?"} H -- Yes --> L["检查 DB I/O:
磁盘 iowait、慢查询"] H -- No --> I{"preprocessor busy > 75%?"} I -- Yes --> J["增加 StartPreprocessors"] I -- No --> M["Cache size 不足
检查 Cache miss"]

内部监控项定位瓶颈:

# 队列深度(主要指标)
zabbix_get -s 127.0.0.1 -k zabbix[queue]                       # 总队列
zabbix_get -s 127.0.0.1 -k zabbix[queue,5m]                    # 5 分钟以上延迟
zabbix_get -s 127.0.0.1 -k 'zabbix[queue,proxy,5m,beijing]'    # 特指 Proxy

# 进程负载
zabbix_get -s 127.0.0.1 -k zabbix[process,poller,avg,busy]     # poller 忙率
zabbix_get -s 127.0.0.1 -k zabbix[process,trapper,avg,busy]
zabbix_get -s 127.0.0.1 -k zabbix[process,historysyncer,avg,busy]
zabbix_get -s 127.0.0.1 -k zabbix[process,preprocessor,avg,busy]

# Cache 命中
zabbix_get -s 127.0.0.1 -k zabbix[cache,buffer,history]         # 历史缓存使用率
zabbix_get -s 127.0.0.1 -k zabbix[cache,buffer,value]           # 值缓存
zabbix_get -s 127.0.0.1 -k zabbix[cache,buffer,historyindex]   # 索引缓存

# 数据库相关
zabbix_get -s 127.0.0.1 -k zabbix[db,wait_time]                 # DB 等待时间
zabbix_get -s 127.0.0.1 -k zabbix[db,query,insert,history]      # 插入次数

典型瓶颈与调优:

现象瓶颈点调优措施
队列堆积 > 10Poller 不足增加 StartPollers
Preprocessor 忙 > 75预处理瓶颈增加 StartPreprocessors
history syncer 忙DB 写入 I/O检查 DB 配置; 启用批量插入; 使用 TimescaleDB
Cache miss 上升缓存不足增大 HistoryCacheSize
DB wait_time 高DB 慢查询检查分区、压缩;分析慢查询日志
SNMP 采集慢SNMP 设备超时Timeout 调低;增加 StartSNMPPollers
Agent 连接超时Agent 端口Agent 端同时启用 ListenPort + ServerActive
Bulk 写入延迟磁盘 I/O分离数据文件至 SSD; commit 调优

Server 配置调优模版:

# 高性能配置(假设 10,000 NVPS)
StartPollers=80
StartTrappers=40
StartPingers=5
StartHTTPPollers=20
StartSNMPPollers=20
StartIPMIPollers=5
StartJMXPollers=10
StartLLD=10
StartPreprocessors=20
StartAlerters=10
StartEscalators=10

# Cache 调大
HistoryCacheSize=512M
HistoryIndexCacheSize=128M
TrendCacheSize=256M
ValueCacheSize=512M

# 数据库相关
CacheUpdateFrequency=60
MaxHousekeeperDelete=50000
HistorySyncer=10
TrendFunctionCacheSize=8M
HistoryCacheSetSize=128M

# 超时
Timeout=3
SNMPTimeout=1
TrapperTimeout=30

OS 层调优:

# 系统参数
kernel.shmmax = 68719476736       # 64GB 共享内存
kernel.sem = 250 32000 100 256    # 信号量(Zabbix 多进程要求)

# 数据库(MySQL)
innodb_buffer_pool_size = 16G     # 总内存 50-70%
innodb_io_capacity = 2000          # SSD
innodb_log_file_size = 2G
innodb_flush_log_at_trx_commit = 2 # 允许 1s 数据丢失提升写入性能
26 Zabbix 7.x 在性能和扩展性方面有哪些重要改进?

答案:

Zabbix 7.x(2024 年发布)在性能和扩展性上带来多项底层改进,包括 Native Agent 2 持久连接、数据库连接池、监控项预处理完全异步化、Server 内部项缓存重构。

Zabbix 7.x 关键改进:

改进影响
持久连接Agent 2 原生长连接,减少连接建立开销,主动模式下批量传递效率倍增
预处理异步化预处理步骤完全异步执行,不再阻塞 poller 进程,单台 Server 可承载更高 NVPS
数据库连接池Server 和 Proxy 支持数据库连接池(DBCacheSize),减少连接建立/关闭开销
双重历史写入history 和 trend 同批入库,减少 I/O 次数
LLD 异步化LLD 发现和处理不再阻塞 Server 主流程,多 LLD 并发
Web 前端 PHP 8.2+仅支持 PHP 8.2/8.3,性能提升 20%+ (vs PHP 7.x)
宏引擎优化宏解析在配置同步时完成,运行时不再解析,大幅降低内存使用
事件处理并发告警事件处理支持多线程并发,避免单个事件队列阻塞

持久连接对比:

Zabbix 6.0:
  Agent 主动模式:每次采集周期 (60s) 建立新连接 → 断开
  Agent A(5000 host)→ Server: 5000次连接建立/60s ≈ 83次/秒 TCP

Zabbix 7.x:
  Agent 2 主动模式:建立长连接,复用
  Agent A(5000 host)→ Server: 2-5个持久 TCP 连接 → 多路复用
  → 减少 Server 端 TCP 状态表压力
  → 减少 Agent 端 fork/exec 开销(Agent 2)

预处理完全异步化:

Zabbix 6.0: 预处理 → poller → 同步等待(polling + preprocessing 串行)
Zabbix 7.x: 预处理 → 异步队列 → preprocessor 空闲进程独立执行

↓ 影响:
  NVPS: +30-80%(预处理密集场景提升最明显)
  CPU 利用率:preprocessor 进程不再与 poller 绑定,可独立控制

数据库连接池:

# Zabbix 7.x Server 配置
DBCacheSize=32M              # 数据库连接池大小(共用的连接状态缓存)
DBMaxPoolSize=100            # 连接池最大连接数
DBPoolIdleSize=64            # 连接池空闲保持数
DBPoolCheckTimeout=300       # 空闲连接回收时间

↓ 影响:
  高并发: 连接池降低建连开销
  慢查询: 池化连接减少等待
  Proxy: 受益尤甚(频繁连接/断开历史模式)

性能对比数据(官方参考):

场景: 10,000 Host × 200 Item = 2,000,000 Item × 60s ≈ 33,333 NVPS

Zabbix 6.0 LTS:
  Server 进程: 100 (poller) + 50 (trapper) + 30 (preprocessor) + ...
  Server 内存: 16-24 GB
  DB: TimescaleDB, 4 核 32G

Zabbix 7.x:
  Server 进程: 60 (poller) + 40 (trapper) + 10 (preprocessor) + ...
  Server 内存: 12-16 GB
  DB: TimescaleDB, 4 核 32G

↓ 提升:
  同 NVPS 下减少 30-50% 进程数
  内存减少 20-40%
  Agent 连接数减少 80%+(持久连接)

升级注意事项:

重要:
  - Agent 2 需升级到 7.x 版本才能使用持久连接
  - PHP 版本必须 ≥ 8.2
  - 数据库 schema 需要迁移(Zabbix 7.0 有额外表结构变更)
  - 旧版 C-Agent 仍可用,但无法享受持久连接优化
  - Proxy 需与 Server 同版本(向下兼容到 6.0 有限)
27 Zabbix API 如何用于批量自动化?常见场景有哪些?

答案:

Zabbix API 基于 JSON-RPC 2.0 协议,HTTP POST 请求到 api_jsonrpc.php,支持对所有 Zabbix 管理对象(主机、模板、Host Group、Item、Trigger、Action、User、Media)的 CRUD 操作,是实现批量自动化、CMDB 同步、CI/CD 集成的关键接口。

API 基础:

# 认证
curl -X POST http://zabbix.example.com/api_jsonrpc.php \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "user.login",
    "params": {"user": "Admin", "password": "zabbix"},
    "id": 1
  }'
# 返回: {"result":"auth_token_xxxx","id":1}

# 后续所有请求携带 auth
AUTH="auth_token_xxxx"

常见自动化场景:

# 场景 1: 批量创建主机
curl -X POST http://zabbix.example.com/api_jsonrpc.php \
  -H "Content-Type: application/json" \
  -d "{
    \"jsonrpc\": \"2.0\",
    \"method\": \"host.create\",
    \"params\": {
      \"host\": \"web-01\",
      \"interfaces\": [
        {\"type\": 1, \"main\": 1, \"useip\": 1, \"ip\": \"10.0.0.1\", \"dns\": \"\", \"port\": \"10050\"}
      ],
      \"groups\": [{\"groupid\": \"5\"}],
      \"templates\": [{\"templateid\": \"10001\"},{\"templateid\": \"10234\"}],
      \"macros\": [
        {\"macro\": \"{$SSH_PORT}\", \"value\": \"22\"}
      ]
    },
    \"auth\": \"$AUTH\",
    \"id\": 2
  }"

# 场景 2: 获取主机 ID 和状态
curl -X POST http://zabbix.example.com/api_jsonrpc.php \
  -H "Content-Type: application/json" \
  -d "{
    \"jsonrpc\": \"2.0\",
    \"method\": \"host.get\",
    \"params\": {
      \"output\": [\"hostid\",\"host\",\"status\"],
      \"filter\": {\"host\": [\"web-01\",\"web-02\"],\"status\": [0]}
    },
    \"auth\": \"$AUTH\",
    \"id\": 3
  }"

# 场景 3: 批量更新主机宏
curl -X POST http://zabbix.example.com/api_jsonrpc.php \
  -H "Content-Type: application/json" \
  -d "{
    \"jsonrpc\": \"2.0\",
    \"method\": \"host.update\",
    \"params\": {
      \"hostid\": \"10234\",
      \"macros\": [
        {\"macro\": \"{$DISK.WARN}\", \"value\": \"85\"}
      ]
    },
    \"auth\": \"$AUTH\",
    \"id\": 4
  }"

# 场景 4: 获取告警事件并确认
curl -X POST http://zabbix.example.com/api_jsonrpc.php \
  -H "Content-Type: application/json" \
  -d "{
    \"jsonrpc\": \"2.0\",
    \"method\": \"event.get\",
    \"params\": {
      \"output\": \"extend\",
      \"severities\": [4,5],
      \"time_from\": \"$(date -d '1 hour ago' +%s)\",
      \"acknowledged\": false
    },
    \"auth\": \"$AUTH\",
    \"id\": 5
  }"

常用 API 方法:

方法操作场景
host.create / host.update / host.delete主机增删改CMDB 同步、自动注册
hostgroup.get / hostgroup.create主机组管理业务分组
template.create / template.export模板 CRUD版本控制
trigger.create / trigger.get触发器管理批量配置
action.create / action.update动作管理告警路由
event.get / event.acknowledge事件查询与确认值班系统集成
history.get / trend.get历史/趋势查询外部报表
dashboard.export / dashboard.importDashboard 导入导出监控看板
maintenance.create / maintenance.delete维护期管理变更窗口
usermacro.get / usermacro.create宏 CRUD参数化
configuration.export / configuration.import配置导入导出Git 备份

Python 自动化示例:

# pip install py-zabbix
from pyzabbix import ZabbixAPI

zapi = ZabbixAPI('http://zabbix.example.com')
zapi.login('Admin', 'zabbix')

# 查询所有激活的主机
hosts = zapi.host.get(output=['hostid', 'host'],
                       filter={'status': 0})
print(f"总激活主机数:{len(hosts)}")

# 批量创建主机
for ip, hostname in cmdb_hosts.items():
    zapi.host.create(
        host=hostname,
        interfaces=[
            {'type': 1, 'main': 1, 'useip': 1, 'ip': ip, 'port': '10050'}
        ],
        groups=[{'groupid': group_id}],
        templates=[{'templateid': tmpl_id}],
        macros=[{'macro': '{$ENV}', 'value': 'prod'}]
    )
    print(f"创建主机 {hostname} ({ip})")

# 批量创建维护期
zapi.maintenance.create(
    name=f"升级维护 {date}",
    hostids=[host_id],
    timeperiods=[
        {'timeperiod_type': 0,
         'start_date': start_ts,
         'period': 3600}  # 1 hour
    ],
    tags_evaltype=0,
    tags=[{'tag': 'source', 'value': 'deploy'}]
)

API 自动化最佳实践:

1. 认证复用: 只 login 一次,auth token 有效期内复用
2. 批量操作: 每次 API 调用可包含多个对象,减少 HTTP 开销
3. 幂等性: host.create → host.get 先检查再 create(防止重复)
4. 错误处理: JSON-RPC 返回 error 时捕获并重试
5. 限速: 单脚本每秒 < 10-20 次 API 调用(Server 端有保护)
6. 配置备份: 定期 configuration.export → Git 仓库(Zabbix 模板版本管理)
7. 与 CMDB 集成: Ansible/Terraform 调用 Zabbix API 自动化主机创建
28 Zabbix 安全加固有哪些关键措施?

答案:

Zabbix 部署在生产环境时需从网络层、传输层、认证层、数据层、API 层五个维度进行安全加固。默认配置以可用性优先,生产部署必须有对应安全策略覆盖。

安全加固全面清单:

层次加固措施配置
传输加密Agent ↔ Server/Proxy:TLS/PSKTLSConnect=psk; TLSAccept=psk
数据库加密DB 连接 TLSDBHost TLS 连接
Web 前端HTTPS onlyNginx/Apache 反向代理 TLS
Web 认证LDAP/SAML/OAuth2Authentication type: LDAP
APIAPI 访问限制 + TokenAPI.access_token 限制
Agent 安全限制 System.RunDenyKey=system.run[*]
Web 前端 IP 限制仅允许内网/IPNginx allow/deny
时区/日志统一时区,日志输出LogFileSize=10, DebugLevel=3
Proxy 加密Proxy ↔ Server TLSTLSConnect=psk
Web 前端密码密码策略(长度、过期)User authentication policy
XSS/SQL 注入PHP 安全配置session.cookie_httponly, csp

TLS/PSK 配置示例:

# 1. 生成 PSK Key
openssl rand -hex 32 > /etc/zabbix/psk.key

# 2. Server 配置
# /etc/zabbix/zabbix_server.conf
TLSConnect=psk
TLSAccept=psk
TLSPSKIdentity=Server1
TLSPSKFile=/etc/zabbix/psk.key

# 3. Agent 配置
# /etc/zabbix/zabbix_agentd.conf
TLSConnect=psk
TLSAccept=psk
TLSPSKIdentity=Agent1
TLSPSKFile=/etc/zabbix/agent_psk.key

# 4. Web UI → Host → Encryption
# 每个主机配置 PSK Identity 和 PSK key
  
# 5. 验证
zabbix_get -s 127.0.0.1 -k agent.ping --tls-connect psk \
  --tls-psk-identity "Server1" --tls-psk-file /etc/zabbix/psk.key

Agent 最小权限:

# /etc/zabbix/zabbix_agentd.conf

# 关键:拒绝危险 Key
DenyKey=system.run[*]
AllowKey=system.run[uptime]

# 或者只允许指定 Key(白名单模式推荐)
# AllowKey 优先于 DenyKey
AllowKey=system.run[*]            # 默认禁止
AllowKey=agent.ping
AllowKey=system.hostname
AllowKey=system.cpu.util[*]
AllowKey=system.uname
AllowKey=net.if.discovery
AllowKey=vfs.fs.discovery

# UserParameter 沙箱化
# 不要在 UserParameter 中调用未验证的输入
# 使用 sudo 限制执行用户
AllowRoot=0                       # 禁止 root 执行远程命令
EnableRemoteCommands=0             # 禁止远程命令(默认)

数据库安全:

-- Zabbix 数据库用户最小权限
CREATE USER 'zabbix'@'%' IDENTIFIED BY 'strong_password_xxxx';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX, REFERENCES
  ON zabbix.* TO 'zabbix'@'%';
-- 注意:Zabbix DBSchema 迁移需要额外权限(如 ALTER TABLE)
-- 但日常运行时不需要 CREATE/DROP/ALTER→可去掉

-- 只读报表用户
CREATE USER 'zabbix_read'@'%' IDENTIFIED BY 'report_password';
GRANT SELECT ON zabbix.* TO 'zabbix_read'@'%';

Web 前端安全:

# Nginx 反向代理
server {
  listen 443 ssl http2;
  server_name zabbix.example.com;
  
  ssl_certificate /etc/ssl/zabbix.crt;
  ssl_certificate_key /etc/ssl/zabbix.key;
  
  # 仅允许内网 IP
  allow 10.0.0.0/8;
  allow 192.168.0.0/16;
  deny all;
  
  # CSP 增强
  add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;";
  
  # 禁用目录列表
  autoindex off;
  
  location / {
    proxy_pass http://127.0.0.1:80;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
  }
}

# PHP 安全配置
session.cookie_httponly = 1
session.cookie_secure = 1
session.use_strict_mode = 1

API 安全:

# Web UI → Administration → API Tokens
# 优点:API Token 比密码更安全(可设置过期、权限范围)

# API Token 使用:
curl -X POST http://zabbix.example.com/api_jsonrpc.php \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer api_token_xxxx" \            ← Bearer token
  -d '{...}'

# API Rate Limiting
# Zabbix 默认没有速率限制,可 Nginx 层实现
limit_req_zone $binary_remote_addr zone=zabbix_api:10m rate=10r/s;

维护期(Maintenance)用于变更安全:

Maintenance: 云环境变更窗口
  - 变更期间自动关闭告警(不产生事件)
  - 维护期过后自动恢复
  - 支持周期性维护期(如每月补丁维护)

创建方式:
  - API: maintenance.create
  - 脚本: zabbix_maintenance.py
  - Web UI: Configuration → Maintenance
29 Zabbix 与 Prometheus + Grafana 在监控体系中的选型对比?

答案:

Zabbix 和 Prometheus 并非非此即彼,现代观测性架构中两者长期共存:Zabbix 负责传统基础设施(物理机、网络设备、数据库中间件),Prometheus 负责云原生(K8s、微服务、容器)。Grafana 作为统一可视化层可以整合两者数据源。

多维度对比:

维度ZabbixPrometheusPrometheus+Grafana
定位中心化多协议监控平台时序数据库 + 告警引擎生态(LGTM 堆栈)
采集模型Agent/SNMP/IPMI/Trapper 多协议主要 Pull + Pushgateway同 Prometheus
数据模型主机-Item 对象模型指标名 + 多维 Label同 Prometheus
告警引擎内置触发器 + Action 升级规则评估 + AlertmanagerAlertmanager 路由
可视化自带 Dashboard + Grafana无(依赖 Grafana)Grafana 为主
模板库内置丰富官方模板社区 Exporter 丰富社区 Exporter + 仪表盘
协议适配SNMP/IPMI/JMX/HTTP Agent 原生需额外 Exporter同 Prometheus
扩展性Proxy 分发 + Server HA联邦 / Thanos / CortexMimir / VictoriaMetrics
运维认知PHP + MySQL/PostgreSQLGo + TSDB多组件运维
K8s 适配需手动配置天然支持完全适配
多语言 SDKC/Go/其他(zabbix_sender)所有主流语言同 Prometheus
数据保留MySQL 行 + Housekeeper块压缩 + 过期策略可配置
告警升级内置(escalation)无(Alertmanager 不提供升级)需外部系统
资产/CMDB内置资产管理(Inventory)

选型决策树:

是否需要监控以下设备:
├─ 物理服务器(温度/IPMI/传感器) → Zabbix(最成熟)
├─ 网络设备(SNMP)               → Zabbix(原生支持)
├─ 数据库/中间件                  → Zabbix 或 Prometheus Exporter
├─ Kubernetes/容器                → Prometheus(标准方案)
├─ 云原生微服务/Service Mesh      → Prometheus + Grafana Tempo
└─ 业务自定义指标                  → Prometheus Client 库

是否已有 Zabbix 基础设施:
├─ 已有 5000+ 监控项               → 扩展 Zabbix 部署
├─ 全面 K8s 化                     → 逐步引入 Prometheus
└─ 混合架构                         → Zabbix(传统层)+ Prometheus(云原生)

团队技能:
├─ 熟悉 PHP/MySQL                  → Zabbix 运维友好
├─ 熟悉 Go/Linux                   → Prometheus 运维友好
└─ 两者兼备                         → 混合架构:统一 Grafana 前端

Grafana 统一可视化:

Grafana → 统一仪表盘入口

数据源一: Zabbix (Zabbix Data Source Plugin)
  - 接入 Zabbix 历史/趋势数据
  - 查询 Zabbix 对象模型(host/group/template)
  - 通过 Zabbix API 获取告警事件

数据源二: Prometheus / Thanos
  - 用 PromQL 查询多维指标
  - Service 级指标聚合展示

数据源三: Loki
  - 日志搜索与面板关联

架构示例:
  Grafana Dashboard:
    ├─ Panel 1: 物理服务器 → Zabbix
    ├─ Panel 2: K8s → Prometheus
    ├─ Panel 3: 日志 → Loki
    └─ Panel 4: 告警 → Alertmanager

混合部署推荐架构:

推荐架构(中大规模):
  
  传统层(Zabbix):
    Zabbix Server HA (3 节点)
    Zabbix Proxy × N (按区域)
    Agent 2 (Linux/Windows)
    SNMP 轮询 (网络设备)
    IPMI (硬件健康)
  
  云原生层(Prometheus + VictoriaMetrics):
    Prometheus Operator (K8s 监控)
    VictoriaMetrics (长期存储)
    Prometheus AlertManager (告警)
  
  观测性层(Grafana + Loki + Tempo):
    Grafana (统一仪表盘)
    Zabbix Datasource Plugin
    Prometheus Datasource
    Loki (日志)
    Tempo (分布式追踪)
  
  统一告警:
    PagerDuty / Opsgenie
    Zabbix Action → Webhook → PagerDuty
    Alertmanager → Webhook → PagerDuty
30 Zabbix 常见故障场景与排查思路?

答案:

Zabbix 生产环境中最常见的故障集中在四个层面:Server 进程挂死、数据库写入瓶颈、采集延迟/队列堆积、Agent 连接问题。以下是主流故障场景的排查流程。

故障 1:Server 进程挂死(高负载)

现象:
  - zabbix_server 运行但无响应
  - 队列堆积(zabbix[queue] > 1000)
  - Agent 连接超时

排查:
  # 1. 检查进程负载
  zabbix_get -s 127.0.0.1 -k zabbix[process,poller,avg,busy]
  zabbix_get -s 127.0.0.1 -k zabbix[process,trapper,avg,busy]

  # 2. 检查 Server 日志
  tail -100 /var/log/zabbix/zabbix_server.log | grep -i error

  # 3. 检查 DB 连接
  zabbix_get -s 127.0.0.1 -k zabbix[db,wait_time]

  # 4. 检查 Cache 使用率
  zabbix_get -s 127.0.0.1 -k zabbix[cache,buffer,history]

修复:
  - 调大 HistoryCacheSize / ValueCacheSize
  - 增加 HistorySyncer 数量
  - 检查慢查询(DB 层)
  - 如果是 Housekeeper 阻塞:停止 Housekeeper + 手动分区 Drop

故障 2:数据库写入瓶颈

现象:
  - history_syncer 进程繁忙 > 75%
  - DB wait_time 高
  - history/trends 插入延迟(INSERT backlog)
  - Server 日志出现 "lost X values"

排查:
  # 1. 检查慢查询
  # MySQL
  SHOW FULL PROCESSLIST;
  SHOW GLOBAL STATUS LIKE 'Innodb_row_lock%';
  
  # 2. 检查数据库 I/O
  iostat -x 1 | grep -E 'sda|nvme'
  iotop -oP

  # 3. 检查 history 表大小
  SELECT table_name, table_rows, ROUND(data_length/1024/1024,2) size_mb
  FROM information_schema.tables
  WHERE table_schema = 'zabbix';

修复:
  - 增大 HistorySyncer / HistoryCacheSize
  - 切换到 TimescaleDB(原生分区 + 压缩)
  - 关闭内置 Housekeeper(用分区 Drop 代替)
  - 增加 DB 并发写入(innodb_io_capacity)

故障 3:Agent 连接失败

现象:
  - Trigger: agent.ping.nodata(300)=1
  - Item 显示 No value
  - zabbix_get 连接超时

排查:
  # Server 端
  zabbix_get -s 192.168.1.10 -k agent.ping -p 10050
  # 返回: ZBX_TCP_READ() timed out

  # Agent 端
  systemctl status zabbix-agent
  zabbix_agentd -t agent.ping

  # 网络检查
  tcpdump -i eth0 port 10050 -c 5

常见原因:
  1. Agent 配置错误(Server IP 不对)
  2. 防火墙阻挡(iptables/nftables/安全组)
  3. Agent 端口被占用(多个 Agent 进程冲突)
  4. 超时太短(Timeout < Agent 响应时间)
  5. TLS/PSK 配置不匹配
  6. 主机名不匹配(Hostname / HostnameItem)

修复:
  - 检查 /etc/zabbix/zabbix_agentd.conf
  - 检查防火墙: nc -zv 192.168.1.10 10050
  - 增加 Timeout = 5 (Server 和 Agent 都改)
  - 验证 TLS 配置:tls-connect / tls-accept 匹配

故障 4:Proxy 离线

现象:
  - Proxy 状态显示 Not available
  - 该区域监控数据全部停止
  - Trigger: "Zabbix proxy is not available"

排查:
  # 1. 检查 Proxy 进程
  systemctl status zabbix-proxy
  tail -100 /var/log/zabbix/zabbix_proxy.log

  # 2. 检查网络
  telnet <Server IP> 10051
  
  # 3. Proxy 配置
  grep -E '^(Server|Hostname|BufferSize|ConfigFrequency|DataSenderFrequency)' \
    /etc/zabbix/zabbix_proxy.conf

  # 4. 检查 Proxy 缓冲文件
  ls -lh /tmp/zabbix_proxy.db

修复:
  - 重启 Proxy: systemctl restart zabbix-proxy
  - 检查 Proxy 与 Server 版本兼容性
  - 增大 BufferSize(网络不稳定场景)
  - 调整 DataSenderFrequency(减小 = 更频繁上报)

故障 5:时间不同步

现象:
  - 历史数据时间错位
  - 触发器评估异常(某些函数依赖 clock 排序)
  - 趋势图显示异常

排查:
  # 所有机器(Server/Agent/Proxy/DB)
  timedatectl status
  ntpq -pn
  chronyc tracking

常见原因:
  - NTP 服务未安装或未配置
  - 虚拟机时钟漂移(尤其是 VMotion 后)
  - 硬件 RTC 与系统时间偏差

修复:
  - 配置统一的 NTP 源
  - 启用 chrony / ntpd
  - VM 场景启用 KVM clock=kvm
  - 验证: ntpdate -q pool.ntp.org

故障 6:Web UI 慢/报错

现象:
  - Dashboard 页面加载 > 10s
  - PHP 报错(`PHP Fatal error: Allowed memory size exhausted`)
  - PHP/DB 连接超时

排查:
  # PHP 配置
  php -i | grep memory_limit    # 应 ≥ 256M
  php -i | grep max_execution_time  # 应 ≥ 300

  # 慢查询
  tail -100 /var/log/mysql/slow-query.log

修复:
  - PHP memory_limit = 256M-512M
  - PHP max_execution_time = 300
  - PHP post_max_size = 32M
  - 开启 PHP OPcache
  - 检查 Web 前端与 Server 版本一致
  - Dashboard 减少历史数据量(增加时间范围限制)

Zabbix 维护常用命令总结:

# Server 状态
systemctl status zabbix-server

# 获取内部指标
zabbix_get -s 127.0.0.1 -k zabbix[queue]
zabbix_get -s 127.0.0.1 -k 'zabbix[queue,5m]'

# 进程负载
zabbix_get -s 127.0.0.1 -k 'zabbix[process,poller,avg,busy]'

# 主动模式测试
zabbix_sender -z 127.0.0.1 -s "test-host" -k test.key -o 1

# 日志
journalctl -u zabbix-server -n 200 --no-pager
tail -f /var/log/zabbix/zabbix_server.log

# 数据库检查
mysql -e "SELECT COUNT(*) FROM proxy_history;"
mysql -e "SHOW ENGINE INNODB STATUS\G" | grep -A5 "HISTORY LIST"

# Housekeeper 监控
zabbix_get -s 127.0.0.1 -k zabbix[housekeeping,start_time]
zabbix_get -s 127.0.0.1 -k zabbix[housekeeping,count]