Windows Server 监控实战:Zabbix Agent + 性能计数器,服务/进程/系统三层告警完整配置指南
目录
- Windows 环境监控的特殊性
- 采集方式选型:一句话结论
- Zabbix Agent 安装与配置
- 系统层监控:CPU / 内存 / 磁盘 / 网络
- 服务层监控:Windows 服务状态告警
- 进程层监控:关键进程存活与资源占用
- Windows 性能计数器:采集定制指标
- 告警规则与分级配置
- 6 个生产踩坑
- 与运维平台结合
- 部署 Checklist
1. Windows 环境监控的特殊性
Windows 服务器的监控,在大多数运维团队里是一个"三不管"地带:Linux 运维不熟 Windows 生态,Windows 管理员不碰 Zabbix,结果就是几十台跑着 ERP、收银系统、MES、域控的生产服务器,在监控平台上只有一个 Ping 状态。
如果你打开 Zabbix 主机列表,看到一堆 Windows 主机只有绿框的"可用"标记,但 CPU、内存、磁盘、服务状态栏全是空的——那说明你就在这个困境里。
这个困境的代价不是抽象的。Windows 服务无声崩溃、磁盘悄悄写满、进程假死——这些问题在 Windows Server 上的发生概率不比 Linux 低,但因为监控缺失,发现时间往往以小时计。而对于连锁门店、制造工厂这类场景,一台门店服务器上的 SQL Server 崩了,影响的是几十家门店的收银开票;一台产线 MES 服务器内存耗尽,卡的是整个班次的生产。
本文给出一套完整的 Windows Server 监控配置方案,覆盖系统层、服务层、进程层三个维度,所有配置均在 Zabbix 6.x 上生产验证。
2. 采集方式选型:一句话结论
Windows 监控有三种采集方式,但选型不需要纠结——首选 Zabbix Agent,只有两种例外用别的:
- 首选:Zabbix Agent(Windows 版),覆盖最全、配置最灵活,本文所有配置基于此方式
- 唯一例外:不允许安装第三方软件的设备(如工控机),用 SNMP 做基础 Ping + 端口检测即可,指标覆盖别指望太多
- 进阶:Zabbix Agent 2 的 WMI 模块能采集 IIS 应用池、COM+ 应用等深度 Windows 指标,但 WMI 查询有性能开销,一般场景用不到,非 IIS/COM+ 场景直接用 Agent 裸 Key 就够了
3. Zabbix Agent 安装与配置
3.1 下载安装
在 https://www.zabbix.com/download 下载对应版本的 Windows MSI 安装包(选 Windows Agent,注意与 Zabbix Server 版本匹配)。
或用 PowerShell 直接下载安装:
# PowerShell(以管理员身份运行)
$version = "6.4"
$url = "https://cdn.zabbix.com/zabbix/binaries/stable/$version/zabbix_agent2-$version.0-windows-amd64-openssl.msi"
Invoke-WebRequest -Uri $url -OutFile "C:\Temp\zabbix_agent2.msi"
# 静默安装,指定 Zabbix Server IP
Start-Process msiexec.exe -ArgumentList @(
"/i", "C:\Temp\zabbix_agent2.msi",
"/qn",
"SERVER=10.0.0.100", # 替换为你的 Zabbix Server IP
"SERVERACTIVE=10.0.0.100",
"HOSTNAME=WIN-STORE-001", # 设置主机名,与 Zabbix 主机名一致
"LOGFILE=C:\Program Files\Zabbix Agent 2\zabbix_agent2.log"
) -Wait
3.2 配置文件关键参数
安装后编辑 C:\Program Files\Zabbix Agent 2\zabbix_agent2.conf:
# Zabbix Server / Proxy 地址(被动监控用)
Server=10.0.0.100
# Zabbix Server 主动监控地址(主动模式用)
ServerActive=10.0.0.100
# 主机名(必须与 Zabbix 前端添加主机时的名称完全一致!)
Hostname=WIN-STORE-001
# 允许远程命令(用于自动化修复脚本)
# AllowKey=system.run[*] # 生产环境谨慎开启,有安全风险
# 自定义监控脚本目录
UserParameter=custom.*,C:\ZabbixScripts\*.ps1
# 日志级别(正常运行后改为 3,debug 级别日志量很大)
DebugLevel=3
# 监听端口
ListenPort=10050
配置完成后重启服务:
Restart-Service "Zabbix Agent 2"
# 验证服务状态
Get-Service "Zabbix Agent 2" | Select Status, StartType
3.3 防火墙放行
# 放行 Zabbix Agent 默认端口
New-NetFirewallRule -DisplayName "Zabbix Agent" `
-Direction Inbound `
-Protocol TCP `
-LocalPort 10050 `
-Action Allow
# 验证
Test-NetConnection -ComputerName 10.0.0.100 -Port 10051
### 3.4 批量部署:PowerShell Remoting 一次覆盖多台
手动逐台安装在管 50 台以上 Windows Server 的场景里完全不现实。用 PowerShell Remoting 可以把 Agent 部署变成流水线作业。
**前提**:目标机器已启用 WinRM(企业内网域环境默认开启;非域环境参考下方一键开启命令)。
```powershell
# 在目标机器上一键开启 WinRM(域外环境用管理员身份运行)
Enable-PSRemoting -Force
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "10.0.0.*" -Force
# deploy_zabbix_agent.ps1
# 批量部署 Zabbix Agent 2 到多台 Windows Server
# 在管理机上以管理员身份运行
$ZabbixServer = "10.0.0.100" # 你的 Zabbix Server IP
$AgentMsiUrl = "https://cdn.zabbix.com/zabbix/binaries/stable/6.4/zabbix_agent2-6.4.0-windows-amd64-openssl.msi"
$LocalMsiPath = "C:\Temp\zabbix_agent2.msi"
$Credential = Get-Credential # 输入有管理员权限的账号
# 目标主机列表(从 CSV 读取,CSV格式: Hostname,IP)
$Targets = Import-Csv "C:\Temp\windows_servers.csv"
# CSV 示例:
# Hostname,IP
# WIN-STORE-001,192.168.1.101
# WIN-STORE-002,192.168.1.102
foreach ($target in $Targets) {
$hostname = $target.Hostname
$ip = $target.IP
Write-Host "[$hostname] 开始部署..." -ForegroundColor Cyan
try {
Invoke-Command -ComputerName $ip -Credential $Credential -ScriptBlock {
param($ZabbixServer, $AgentMsiUrl, $LocalMsiPath, $HostnameParm)
# 1. 下载 MSI(如果内网有文件服务器,改成 UNC 路径更快)
if (-not (Test-Path $LocalMsiPath)) {
New-Item -ItemType Directory -Path (Split-Path $LocalMsiPath) -Force | Out-Null
Invoke-WebRequest -Uri $AgentMsiUrl -OutFile $LocalMsiPath -UseBasicParsing
}
# 2. 静默安装
$args = "/i $LocalMsiPath /qn SERVER=$ZabbixServer SERVERACTIVE=$ZabbixServer HOSTNAME=$HostnameParm"
Start-Process msiexec.exe -ArgumentList $args -Wait
# 3. 开防火墙
New-NetFirewallRule -DisplayName "Zabbix Agent" -Direction Inbound `
-Protocol TCP -LocalPort 10050 -Action Allow -ErrorAction SilentlyContinue
# 4. 确认服务状态
$svc = Get-Service "Zabbix Agent 2" -ErrorAction SilentlyContinue
if ($svc -and $svc.Status -eq "Running") {
Write-Output "OK"
} else {
Write-Output "FAILED"
}
} -ArgumentList $ZabbixServer, $AgentMsiUrl, $LocalMsiPath, $hostname
Write-Host "[$hostname] 部署完成" -ForegroundColor Green
} catch {
Write-Host "[$hostname] 部署失败: $_" -ForegroundColor Red
}
}
选 PowerShell Remoting 而不是 SCCM 或 GPO,是因为我们的实际场景是几十台门店服务器分散在不同网段、没有统一域控。SCCM 对这种零散部署太重了,GPO 需要域环境。PowerShell Remoting 的代价只是一个 Enable-PSRemoting,对于没有域的门店/工厂网络是最务实的方案。
部署完成后,在 Zabbix Server 侧批量注册主机。手工在 Web 前端逐个添加主机同样不现实——好在 Zabbix 提供了完整的 JSON-RPC API,一个 bash 脚本就能批量搞定。关键参数说明:groupid 和 templateid 需要根据你自己 Zabbix 环境的实际 ID 替换(在 Zabbix 前端 URL 中可以看到),端口 10050 是 Agent 被动模式的默认监听端口:
# 用 Zabbix API 批量注册(Linux Bash 示例)
ZABBIX_URL="http://10.0.0.100/zabbix/api_jsonrpc.php"
AUTH_TOKEN=$(curl -s -X POST $ZABBIX_URL \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"user.login","params":{"user":"Admin","password":"zabbix"},"id":1}' \
| python3 -c "import sys,json; print(json.load(sys.stdin)['result'])")
# 读取 CSV 批量创建主机
while IFS=',' read -r hostname ip; do
curl -s -X POST $ZABBIX_URL \
-H "Content-Type: application/json" \
-d "{\"jsonrpc\":\"2.0\",\"method\":\"host.create\",\"params\":{\"host\":\"$hostname\",\"interfaces\":[{\"type\":1,\"main\":1,\"useip\":1,\"ip\":\"$ip\",\"dns\":\"\",\"port\":\"10050\"}],\"groups\":[{\"groupid\":\"10\"}],\"templates\":[{\"templateid\":\"10081\"}]},\"auth\":\"$AUTH_TOKEN\",\"id\":2}"
done < <(tail -n +2 windows_servers.csv)
4. 系统层监控:CPU / 内存 / 磁盘 / 网络
在 Zabbix 前端添加主机后,应用 Windows by Zabbix Agent 2 模板(Zabbix 内置),自动覆盖以下系统层指标:
| 指标 | Zabbix Key | 说明 |
|---|---|---|
| CPU 使用率 | system.cpu.util[,idle] |
建议告警阈值:>85% 持续 5 分钟 |
| 内存使用率 | vm.memory.size[pused] |
建议告警阈值:>88% 持续 5 分钟 |
| 磁盘剩余空间 | vfs.fs.size[C:,pfree] |
建议告警阈值:剩余 <15% |
| 磁盘 I/O 等待 | perf_counter[\PhysicalDisk(_Total)\% Disk Time] |
持续高于 80% 说明 I/O 瓶颈 |
| 网络发送速率 | net.if.out[以太网,bytes] |
监控各网卡,注意接口名称 |
关键注意:Windows 磁盘剩余告警要对每个驱动器单独配置。C: 系统盘和数据盘(D:、E:)有不同的告警阈值。
这几个系统层指标看起来和 Linux 监控一样,但 Windows 上有两个容易被忽视的差别:一是 Windows 的磁盘 I/O 比 Linux 更容易成为瓶颈——NTFS 文件系统在大量小文件场景下的性能退化比 ext4/xfs 更明显;二是 Windows 的内存管理机制不同,Available MBytes 比 % Committed Bytes 更能反映实际可用内存,因为 Windows 会积极使用 SuperFetch 预加载,只看空闲内存容易误判。

4.1 系统层指标告警阈值速查表
| 指标 | Zabbix Key | WARNING | CRITICAL | 第一步排查 |
|---|---|---|---|---|
| CPU 使用率 | system.cpu.util[,idle] |
>75%/5min | >90%/5min | Get-Process | Sort CPU -Desc | Select -First 10 |
| 内存使用率 | vm.memory.size[pused] |
>80%/5min | >92%/5min | Get-Process | Sort WorkingSet -Desc | Select -First 10 |
| C: 磁盘剩余 | vfs.fs.size[C:,pfree] |
<15% | <5% | Get-ChildItem C:\ -Recurse -ErrorAction SilentlyContinue | Sort Length -Desc | Select -First 20 |
| 数据盘剩余 | vfs.fs.size[D:,pfree] |
<20% | <8% | 检查日志/备份目录 |
| 磁盘 I/O 等待 | perf_counter[\PhysicalDisk(_Total)\% Disk Time] |
>70% | >90% | 找高 I/O 进程:Get-Counter '\Process(*)\IO Data Bytes/sec' |
| 网络带宽占用 | net.if.out[以太网,bytes] |
>70% 链路 | >90% 链路 | Get-NetAdapterStatistics |
| 系统运行时长 | system.uptime |
— | <30min(非计划重启) | 查事件日志 6008/1074 |
这张表可以直接打印贴在值班室——告警触发后第一步该查什么,一列之内就能确定。
4.2 多驱动器磁盘告警注意事项
Windows Server 经常有多个驱动器(C: 系统盘、D: 数据盘、E: 备份盘),Zabbix 内置模板默认只监控 C: 盘。在部署时需要在 Windows 上确认实际有哪些驱动器,然后为每个驱动器单独配置告警。
快速确认驱动器列表的命令:Get-PSDrive -PSProvider FileSystem | Select Name, Used, Free。
注意区分系统盘和数据盘的告警阈值:C: 盘建议 WARNING <15%、CRITICAL <5%(系统盘满了会导致服务不可用);数据盘可以放宽到 WARNING <20%、CRITICAL <8%,但如果数据盘存的是数据库文件或日志,建议和 C: 盘用同样严格的阈值——我们在一个制造业客户那里见过 D: 盘剩余 12% 时 SQL Server 已经开始报空间不足的 Warning 日志了。
5. 服务层监控:Windows 服务状态告警
Windows 服务状态监控是 Linux 监控工程师最容易遗漏的部分。
5.1 批量监控所有自动启动服务
Zabbix 内置 Key service.info[服务名,state] 可以采集单个服务状态,但手动配置每个服务效率太低。推荐用 LLD(低级发现)自动发现:
在 Zabbix 中创建发现规则:
# Zabbix 发现规则配置(在前端操作)
Discovery Rule Name: Windows Services Discovery
Key: service.discovery
Update interval: 1h
# 过滤条件:只监控启动类型为"自动"的服务
Filter:
- Macro: {#SERVICE.STARTUPNAME}
Regex: ^Auto$
发现后自动为每个服务创建监控项和告警触发器。
这个 LLD 方案的关键设计决策是只监控启动类型为 Auto 的服务。为什么不监控所有服务?因为 Windows Server 上有大量"手动(触发器启动)"的服务,平时是停止状态(比如 Windows Update、各种一次性任务服务),如果全部纳入监控,每天会产生大量"服务已停止"的噪音告警。我们的经验是:Auto 类型覆盖了所有"应该一直运行"的服务,漏掉的风险极低。
5.2 手动监控关键业务服务
对 ERP、收银、SQL Server 等关键服务,额外创建高优先级触发器:
# 在 Zabbix 前端创建 Item
Item name: SQL Server Service Status
Key: service.info[MSSQLSERVER,state]
Type: Zabbix Agent (active)
Value type: Numeric (unsigned)
Update interval: 60s
# 触发器
Trigger name: SQL Server Service Down on {HOST.NAME}
Expression: last(/主机名/service.info[MSSQLSERVER,state])<>0
Severity: High
用 PowerShell 验证服务状态采集:
# 在 Zabbix Server 侧用 zabbix_get 测试
# zabbix_get -s 10.x.x.x -k "service.info[MSSQLSERVER,state]"
# 返回 0 = 运行中,1 = 已停止,2 = 暂停,7 = 未安装
# 本地快速测试(在 Windows 上执行)
Get-Service MSSQLSERVER | Select Status
5.3 Windows 服务状态值速查
| 返回值 | 含义 |
|---|---|
| 0 | Running(运行中) |
| 1 | Stopped(已停止) |
| 2 | Start Pending |
| 3 | Stop Pending |
| 4 | Continue Pending |
| 5 | Pause Pending |
| 6 | Paused(已暂停) |
| 7 | Not Installed(服务不存在) |
6. 进程层监控:关键进程存活与资源占用
服务可以"运行中"但进程已经假死——这个问题在 Windows 上比 Linux 更常见。Windows 服务控制管理器(SCM)只检测进程是否存在,不检测进程是否在正常工作。我们遇到过 SQL Server 服务状态显示 “Running”,但实际进程已经死锁,CPU 100% 卡死,所有查询超时。
这就是进程层监控存在的原因——它绕过 SCM,直接检查进程本身。
6.1 进程存活监控
# Item 配置
Key: proc.num[sqlservr.exe]
# 返回运行中该名称进程的数量
# 触发器:SQL Server 进程消失
Expression: last(/主机名/proc.num[sqlservr.exe])=0
Severity: Disaster
6.2 进程 CPU / 内存占用
# 进程 CPU 占用(百分比)
Key: proc.cpu.util[sqlservr.exe]
# 进程内存占用(字节)
Key: proc.mem[sqlservr.exe,rss]
# 触发器:SQL Server 进程内存超过 8GB
Expression: last(/主机名/proc.mem[sqlservr.exe,rss])>8589934592
Severity: Warning
6.3 用 PowerShell 自定义进程监控脚本
# C:\ZabbixScripts\check_process_cpu.ps1
param([string]$ProcessName)
$proc = Get-Process -Name $ProcessName -ErrorAction SilentlyContinue
if (-not $proc) {
Write-Output "0"
exit
}
# 获取进程 CPU 使用率(需要采样间隔计算)
$cpu = (Get-Counter "\Process($ProcessName)\% Processor Time" -SampleInterval 2 -MaxSamples 1).CounterSamples.CookedValue
[Math]::Round($cpu / (Get-WmiObject Win32_ComputerSystem).NumberOfLogicalProcessors, 2)
在 Agent 配置文件中注册:
UserParameter=proc.cpu.custom[*],powershell -NoProfile -ExecutionPolicy Bypass -File "C:\ZabbixScripts\check_process_cpu.ps1" -ProcessName $1
7. Windows 性能计数器:采集定制指标
Windows 性能计数器(Performance Counter)是最完整的指标来源,几乎所有 Windows 组件都暴露了 PerfCounter。
7.1 常用 PerfCounter Key
以下是我们生产环境中实际在用的 PerfCounter 指标,每个都附上"为什么要监控":
# ASP.NET 请求队列长度(IIS 场景)
# 队列积压意味着 IIS 处理能力跟不上请求量,是应用池回收/死锁的第一信号
perf_counter[\ASP.NET\Requests Queued]
# IIS 每秒请求数
# 建立基线之后,突降=上游出问题,突增=可能在被刷
perf_counter[\Web Service(_Total)\Get Requests/sec]
# SQL Server 每秒事务数
# 监控业务量的间接指标,突降可能意味着数据库阻塞
perf_counter[\SQLServer:Databases(_Total)\Transactions/sec]
# SQL Server 缓存命中率(越接近100越好,低于90需关注)
# 低于90意味着 SQL Server 经常需要从磁盘读数据页,通常是因为内存不够
perf_counter[\SQLServer:Buffer Manager\Buffer cache hit ratio]
# 磁盘平均读取延迟(毫秒)
# 超过20ms说明存储层有性能问题,可能影响所有依赖磁盘的服务
perf_counter[\PhysicalDisk(0 C:)\Avg. Disk sec/Read,1000]
这些 PerfCounter 路径都是英文版 Windows 的格式。如果你在中文版 Windows 上使用,记得先用 7.3 节的脚本做路径验证。
7.2 如何找到可用的 PerfCounter 路径
不同 Windows 版本和已安装组件会影响可用的 PerfCounter 列表。在添加自定义监控项之前,先确认目标计数器是否存在:
# 查看 SQL Server 相关的所有 PerfCounter 指标
(Get-Counter -ListSet "SQLServer:Buffer Manager").Paths
# 实时采样测试——确认路径有效且能返回数值
Get-Counter "\SQLServer:Buffer Manager\Buffer cache hit ratio"
如果 Get-Counter -ListSet 找不到预期的类别,说明对应的 Windows 组件没有安装或版本不兼容。比如 SQLServer:Buffer Manager 只存在于安装了 SQL Server 的机器上,Web Service 系列只存在于启用了 IIS 的机器上。不要在模板里为所有主机配置这些指标——用主机群组或宏来控制哪些主机启用哪些 PerfCounter 监控项。
### 7.3 批量验证 PerfCounter 在中文/英文 Windows 上是否可用
```powershell
# check_perf_counters.ps1
# 批量检查一组 PerfCounter 路径在当前 Windows 上是否能正常采集
# 在部署 Zabbix 模板前跑这个脚本,提前发现 Not Supported 问题
$CountersToCheck = @(
"\Processor(_Total)\% Processor Time",
"\Memory\Available MBytes",
"\PhysicalDisk(_Total)\% Disk Time",
"\PhysicalDisk(_Total)\Avg. Disk sec/Read",
"\SQLServer:Buffer Manager\Buffer cache hit ratio",
"\SQLServer:Databases(_Total)\Transactions/sec",
"\Web Service(_Total)\Get Requests/sec",
"\ASP.NET\Requests Queued"
)
Write-Host "检查 PerfCounter 可用性..." -ForegroundColor Cyan
$results = @()
foreach ($counter in $CountersToCheck) {
try {
$val = (Get-Counter $counter -SampleInterval 1 -MaxSamples 1 -ErrorAction Stop).CounterSamples.CookedValue
$results += [PSCustomObject]@{ Counter=$counter; Status="OK"; Value=[Math]::Round($val,2) }
} catch {
# 中文版 Windows 路径失败时,尝试用 typeperf 找本地化名称
$localName = typeperf -q 2>$null | Where-Object { $_ -match ($counter -replace '.*\\','') } | Select-Object -First 1
$results += [PSCustomObject]@{ Counter=$counter; Status="FAIL"; Value=if($localName){"可能本地化为: $localName"}else{"未找到"} }
}
}
$results | Format-Table -AutoSize
$failCount = ($results | Where-Object {$_.Status -eq "FAIL"}).Count
Write-Host "总计: $($results.Count) 个,通过: $($results.Count - $failCount) 个,失败: $failCount 个" -ForegroundColor $(if($failCount -gt 0){"Red"}else{"Green"})
这个脚本不是凭空想出来的。有一次我们给一家制造企业部署 30 台车间 Windows Server 的 Zabbix 监控,模板批量应用之后,有 7 台中文版 Windows 的 PerfCounter 指标全部显示 Not Supported。在 Zabbix 前端排查 Not Supported 的原因很痛苦——你不知道是 Agent 没装好、网络不通、还是路径问题。挨台远程上去用 typeperf -q 逐个确认,3 个人花了整整一个下午才把所有路径纠正过来。
那之后我们就把这个检查做成了部署前置脚本——接新机器先跑这个,5 秒出结果,哪台有问题、哪些路径要本地化,一目了然。其实所有"看起来很简单的脚本",背后都是一个不想再重复的坑。
8. 告警规则与分级配置
8.1 告警分级参考表
| 级别 | 触发条件 | 示例 |
|---|---|---|
| Disaster | 核心服务/进程消失 | SQL Server 进程消失、AD 认证服务停止 |
| High | 磁盘剩余 <5%、内存 >95% | 系统盘快满、内存即将耗尽 |
| Average | CPU >85%/5min、内存 >88%/5min | 性能指标持续高位 |
| Warning | 磁盘剩余 <15%、IIS 请求队列积压 | 容量预警、性能下降 |
| Info | 系统重启、服务重启恢复 | 非预期重启需要关注原因 |
8.2 系统重启检测
# Item:系统启动时间
Key: system.uptime
Value type: Numeric (float)
Units: uptime
# 触发器:检测非计划重启(如果 uptime < 30 分钟且不在维护期)
Trigger name: Unexpected reboot on {HOST.NAME}
Expression: last(/主机名/system.uptime)<1800
Severity: Average
9. 6 个生产踩坑
以下每个坑都是我们在连锁门店、制造业场景中实际踩过的。问题本身可能看起来不大,但每个坑的排查过程都至少耗费了半天——分享出来的目的就是让你跳过这些排查。
坑1:Agent 配置的 Hostname 与 Zabbix 前端主机名不匹配
这是最高频的问题。Agent 配置的 Hostname=WIN-STORE-001,但 Zabbix 前端添加主机时写的是 win-store-001(小写),导致主动检测数据无法上报,被动检测正常。结果:部分指标有值,部分指标显示 Not Supported。
排查:Zabbix Server 日志 /var/log/zabbix/zabbix_server.log 里搜 Hostname。主机名区分大小写。
这个坑在批量部署时最容易出现——PowerShell 脚本里用
$env:COMPUTERNAME拿到的是全大写,而有人手动在前端添加主机时习惯用首字母大写。50台机器部署完发现30台主动监控不工作,就是这个原因。
坑2:磁盘驱动器名称中文乱码
部分 Windows Server 的磁盘分区名称包含中文(如"本地磁盘"),用 LLD 自动发现时宏 {#FSNAME} 中的中文在 Zabbix Item Key 里会乱码,导致监控项创建失败。
解决:在 LLD 过滤器里限制只监控字母+冒号格式的路径(如 C:、D:),排除中文路径:
Filter: {#FSNAME} matches ^[A-Za-z]:$
坑3:性能计数器路径在不同语言版本 Windows 上名称不同
中文版 Windows 和英文版 Windows 的 PerfCounter 路径不一样。英文版 \Processor(_Total)\% Processor Time,中文版可能是 \处理器(_Total)\% 处理器时间。
Zabbix 内置的 Windows 模板使用的是英文路径,在中文 Windows 上会返回 Not Supported。
解决:用 typeperf 命令在目标 Windows 上确认实际路径:
typeperf -q "Processor" | Where-Object { $_ -match "Processor Time" }
然后在 Zabbix Item 里使用本地实际路径,或切换使用 system.cpu.util 等 Agent 内置 Key(不依赖 PerfCounter)。
这个坑我们在第7.3节讲了具体踩坑经历——7台中文版 Windows 全返回 Not Supported,排查了整整一个下午。教训就是:模板部署之前先跑 check_perf_counters.ps1。
坑4:Zabbix Agent 在 Windows Server 2022 上无法启动
现象:安装成功,但服务启动失败,事件日志里有 “The Zabbix Agent service terminated with service-specific error Incorrect function.”
原因:通常是 OpenSSL 版本不兼容,或下载的 Agent 版本不对(分 x86 和 x64,以及 OpenSSL / GnuTLS 两个加密库版本)。
解决:从 Zabbix 官方下载页面选择 Windows Server 2022 对应的 openssl 版本,且确认 x64(大多数现代 Windows Server 都是 x64)。
坑5:监控 IIS 应用池但实例名包含空格
IIS 应用池名称如 “Default App Pool” 含有空格,放进 PerfCounter Key 时会报错。
解决:使用下划线替代空格,或用引号包裹:
perf_counter_en["\Process(w3wp#0)\% Processor Time"]
用 Get-Counter 先测试确认实际实例名。
坑6:Windows 防火墙阻断 Zabbix 主动监控
被动模式(Server 轮询 Agent)可以正常工作,但主动模式(Agent 向 Server 汇报)数据缺失。
原因:Windows 防火墙的出站规则默认允许所有出站,但部分安全加固过的环境限制了出站,导致 Agent 无法主动连接 Server 的 10051 端口。
解决:检查出站规则,放行 Zabbix Server IP 的 10051 端口出站连接。
这个坑比较隐蔽,因为被动监控一切正常,很容易让人觉得"Agent 配好了"。排查技巧:在 Windows 上用
Test-NetConnection -ComputerName 你的ZabbixServerIP -Port 10051验证出站连通性,不通就查防火墙出站规则。
10. 与运维平台结合
实事求是的说,这套方案在 50 台以内的 Windows Server 规模下跑得很稳,但当机器数超过 100 台、而且中英文 Windows 版本混布时,维护成本会非线性增长:新入一台中文版要单独验证 PerfCounter 路径、Zabbix Agent 版本升级要逐台跟进、LLD 规则对不同 Windows Server 版本偶尔不兼容需要单独处理。
我们在维护了大概半年之后,把这套 Windows Server 监控整体迁移到了冠服云EMS平台的 ITOM 模块,主要解决了两件事:一是 Windows Server 的纳管变成平台内置能力,不再需要单独维护一套 Agent 集群和模板体系;二是门店侧有新设备上线时注册一次就能自动下发监控策略,不需要走"装 Agent → 改配置 → 前端加主机 → 验指标"的完整流程。
当然,如果你已经在用 Zabbix 且规模不大,本文的方案完全够用。只是当 Windows 服务器数量开始往 3 位数走的时候,值得考虑是否需要把监控能力从"手工搭建"升级为"平台内置"。

11. 部署 Checklist
安装阶段
- 确认 Zabbix Agent 版本与 Server 版本匹配(主版本号一致)
- 确认下载 x64 版本(大多数 Windows Server 是 x64)
- 安装后确认
Zabbix Agent 2服务为"自动"启动状态 - 防火墙放行入站 TCP 10050(被动模式)/ 出站 TCP 10051(主动模式)
配置阶段
-
Hostname参数与 Zabbix 前端主机名大小写完全一致 -
Server和ServerActive填写正确的 Zabbix Server/Proxy IP - 在 Zabbix 前端添加主机,应用
Windows by Zabbix Agent 2模板 - 验证:等待 5 分钟后,主机状态变绿,指标有最新数据
监控覆盖阶段
- 系统层:CPU / 内存 / 磁盘 / 网络 指标均有值(不是 Not Supported)
- 确认磁盘监控覆盖所有驱动器(C: / D: / E: 等)
- 关键服务监控(SQL Server / IIS / AD 等)已单独创建高优先级触发器
- 关键进程存活监控已配置
- 所有 PerfCounter Key 在目标 Windows 语言版本上已验证不报 Not Supported
告警阶段
- Disaster 级别告警测试:停止 SQL Server 服务,确认告警到达
- 系统重启检测触发器已配置
- 各驱动器磁盘预警阈值已按实际情况设置(系统盘和数据盘阈值不同)
运营阶段
- 告警已对接工单系统或即时通知渠道,有明确负责人
- 每季度检查 Not Supported 指标列表,修复失效采集
- 新增 Windows 服务器时,有标准化注册流程(不靠人记)
觉得有用的话点个赞/收藏,Windows Server 监控这套配置跑通之后,新机器接入就是套模板的事,比每次现查文档快多了。
相关内链
CSDN-47(连锁门店Zabbix架构) :https://blog.csdn.net/weixin_70758133/article/details/161445385?spm=1011.2415.3001.5331
CSDN-04(告警降噪):
https://blog.csdn.net/weixin_70758133/article/details/158572672?spm=1011.2415.3001.5331
参考资料
- Zabbix 官方 Windows Agent 安装文档
- Zabbix API 官方参考
- 往期相关文章:连锁门店 Zabbix Proxy 分布式监控架构 | 多源告警统一接入方案(站内链接,发布时替换为实际文章 URL)
- Windows Performance Counters 官方文档
更多推荐


所有评论(0)