ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Windows服务器监控实践:Prometheus+node_exporter+Grafana部署全记录

Windows服务器监控实践:Prometheus+node_exporter+Grafana部署全记录 上个月朋友公司一台Windows Server出了问题现象很诡异CPU每隔几小时就飙到90%以上持续三五分钟又自己降下来任务管理器根本没法看出规律事件查看器里也干干净净。后来我用GrafanaPrometheusnode_exporter这套组合在Windows上搭了一套监控半天就把问题锁定了。这篇就完整记录这套环境的配置过程和中间踩过的坑希望能帮你少走点弯路。文章偏实操适合三类人看一是经常被Windows服务器性能问题搞得焦头烂腾的运维二是想要把Windows主机纳入统一监控体系但不知道从哪下手的人三是正在学习Prometheus生态、想找个真实场景练手的同学。我会从架构选型讲到面板配置再讲到告警规则整个链路串起来。1. 为什么Windows监控偏偏选了这套组合而不是别的1.1 一个真实场景说明问题朋友那台服务器的CPU尖峰问题用常规手段排查起来特别麻烦。任务管理器只能看到当下这一刻的进程状态等你去点开看的时候尖峰已经过去了。性能监视器perfmon倒是能记录数据但配置麻烦数据是存成blg文件还是SQL库要看半天文档而且想跨机器汇总得更费劲。更关键的是问题可能是隔几个小时出现一次甚至半夜出现。你不可能一直盯在屏幕前。当时我需要的是一个能长期、自动、无感采集数据的方案数据要能存下来随时可以回溯几小时甚至几周之前的指标曲线。这套组合的核心价值就在这里Prometheus负责定时去采集数据并存储node_exporter负责在Windows主机上暴露指标Grafana负责把数据画成图。1.2 选型逻辑凭什么不是Zabbix也不是ELK很多人在Windows监控上首先会想到Zabbix毕竟功能全面、自带告警。但Zabbix在Windows上的Agent虽然好用整个体系却偏重“被管服务器”的思路配置一个监控项要定义模板、应用模板、建触发器概念比较多。如果你已经有Prometheus监控Linux服务器的经验再在Windows上复用这套学习成本几乎为零整个语法体系也统一。ELK那套其实是拿Filebeat采集日志、Logstash处理、Elasticsearch存重点是日志而非指标。虽然也能做监控但重量级摆在那光一个ES集群的内存开销一般团队就吃不消。Prometheus的特点是单二进制文件自带时序存储node_exporter也是单文件Grafana虽然要大一点但也是绿色安装整套跑起来占用的资源远低于ELK。还有一点这套组合的生态特别成熟。Grafana社区里有大量现成的Windows监控面板导入之后基本不用怎么改就能用。告警规则怎么写、指标怎么算网上资料一堆。这种“抄作业”的便利性是自研监控脚本完全比不了的。2. 装之前先把端口、目录、版本这些硬骨头啃掉2.1 三件套版本选择与下载渠道这里先给出一份我实测过的版本搭配直接照着选不容易踩版本兼容性的坑组件推荐版本说明Prometheus2.53.x持续更新中配置格式和API均向下兼容node_exporter1.8.x老版本对Windows新版本的指标支持有限Grafana11.x支持Windows直接安装的zip包Alertmanager0.27.x如果做告警建议一起装下载渠道分两类。Prometheus、node_exporter、Alertmanager直接去GitHub的官方release页面找windows-amd64后缀的压缩包Grafana去官网下载选择Windows ZIP版。这里要提醒一句网上很多第三方下载站会捆绑修改版虽然能从界面判断出来但这种改编过的agent长期跑在服务器上风险不可控还是从官方渠道下载稳妥。下载完别急着解压先用Get-FileHash命令算一下SHA256和官方页面公布的校验值对比一致再用。2.2 端口、目录与运行账号规划端口分配我建议固定下来方便以后防火墙策略和安全组规则的管理组件默认端口用途node_exporter9100暴露Windows主机指标Prometheus9090Web管理界面与数据查询Grafana3000可视化界面Alertmanager9093告警通知中转目录规划上我习惯在D盘单独建一个D:\monitoring目录下面再分prometheus、node_exporter、grafana、alertmanager四个子目录和组件一一对应。不要放在C:\Program Files下面因为Windows服务默认对Program Files目录有权限保护解压后的程序写自己的数据文件可能遭遇权限问题。放在D盘根目录下服务运行账号给最小化NTFS权限就够了。运行账号建议单独建一个普通用户比如monitor_svc千万别用LocalSystem跑所有组件。LocalSystem权限太高一旦漏洞被利用整个主机等于沦陷。用普通账号跑的话只需要给对应的监控目录授予修改权限即可。这是我做过最小权限改造后比较满意的方案。2.3 安装前后要做的环境检查Windows上跑这套东西不需要单独装运行时node_exporter和Prometheus都是Go编译的静态二进制文件拿到就能跑。但有三件事要提前确认系统时间。Prometheus对采集时间戳有容忍度但Windows系统如果开了自动同步且时区设置不对会出现“数据有值但图上是一条线”的诡异现象。PowerShell执行策略。如果你后续要写自动化检测脚本记得把执行策略设为RemoteSigned。Defender实时保护。这个放最后讲踩坑的时候细说。3. node_exporter在Windows上的正确打开方式3.1 解压部署与运行验证先把下载好的node_exporter-*.windows-amd64.tar.gz解压到D:\monitoring\node_exporter里面其实就一个exe文件加一些文档。首次运行先在命令行模式试一下确认能正常监听端口cd D:\monitoring\node_exporter .\node_exporter.exe --web.listen-address:9100看到msgListening on address:9100之类的日志输出说明进程起来了。这时在本机浏览器访问http://localhost:9100/metrics能看到一堆以node_开头的指标文本。这些就是暴露给Prometheus抓取的原始数据。3.2 注册成Windows服务sc.exe和NSSM的取舍命令行窗口一关进程就没了所以必须注册成Windows服务开机自启。Windows注册服务有两种常用方式。方式一sc.exe注册sc.exe create node_exporter binPath D:\monitoring\node_exporter\node_exporter.exe --web.listen-address:9100 start auto用sc.exe要注意一个反直觉的坑等号后面必须有一个空格binPath和start后面不空格就报语法错误。而且sc创建的服务默认以LocalSystem运行如果想换账号得额外写个bat转投服务操作起来不够直观。方式二NSSMNon-Sucking Service ManagerNSSM可以看作是图形化的服务管理工具参数配置都在交互界面里完成。把nssm.exe放到一个固定目录然后D:\monitoring\nssm\nssm.exe install node_exporter会弹出来一个配置窗口在Application选项卡里填上exe路径D:\monitoring\node_exporter\node_exporter.exe在Arguments里填--web.listen-address:9100在Log on选项卡里配置我们之前说的运行账号和密码。NSSM还自带日志重定向功能自动把stdout和stderr写入指定文件排查问题非常有用。两个方式我都长期用过个人更推荐NSSM不是因为它功能多而是它处理服务异常退出的逻辑更成熟会自动尝试重启进程对监控采集这种需要7x24小时在线的场景很关键。3.3 防火墙放行与远端采集验证服务起来之后远端机器还访问不了9100端口得放行防火墙。Windows防火墙添加规则用管理员权限的命令行操作netsh advfirewall firewall add rule namenode_exporter dirin actionallow protocolTCP localport9100然后从另一台机器验证curl http://Windows主机IP:9100/metrics能拉到指标就说明网络链路通了。如果拉不到先检查刚才的防火墙规则再确认服务是否还在运行最后看下Windows网络配置文件是不是“公用网络”——公用网络的防火墙策略往往更严格单独放行规则可能不够需要调整网络配置文件类型。3.4 Windows 指标有哪些值得优先关注node_exporter在Windows上采集的指标和Linux版本略有不同Windows版通过WMI获取数据指标大致分为CPU、内存、磁盘、网络、系统五大类。比较常用的是node_cpu_seconds_total node_memory_MemTotal_bytes node_memory_MemAvailable_bytes node_disk_read_bytes_total node_disk_written_bytes_total node_network_receive_bytes_total node_network_transmit_bytes_total node_time_seconds第一次能拉到指标后强烈建议手动执行一次查询验证数据是否正常变化避免后面Grafana配完了发现指标本身就为空。查询方式可以用Prometheus自带的表达式浏览器这个放到下一节讲。4. Prometheus服务端配置数据能不能采到就看这步4.1 prometheus.yml 核心配置逐行拆解Prometheus解压后的目录里自带一个prometheus.yml这是唯一需要深度定制的主配置文件。我贴一份生产环境在用的配置加上逐段说明global: scrape_interval: 15s evaluation_interval: 15s external_labels: monitor: windows-monitoring rule_files: - rules/*.yml scrape_configs: - job_name: prometheus static_configs: - targets: [localhost:9090] - job_name: windows static_configs: - targets: - 192.168.1.101:9100 - 192.168.1.102:9100 labels: os: windows几个关键参数说下意思。-scrape_interval是Prometheus去抓取指标的频率生产环境15秒是比较常见的折中方案想更细致可以调成5秒但存储和网络开销会翻几倍。-rule_files指向告警规则目录后面讲告警时再展开。-static_configs就是静态目标列表Prometheus会按job去归类这些目标Grafana面板里也经常按job过滤数据。配置完成后用promtool check config prometheus.yml做一次语法校验没有问题再启动。启动后访问http://Prometheus所在机器IP:9090/targets就能看到所有配置的抓取目标。State为UP表示抓取成功。这一步是整个监控链路里最容易排查问题的节点因为你能直观看到Prometheus到底连没连上目标。4.2 多场景多主机的job规划思路生产环境往往不止一台Windows机器可能是几台Web服务器加几台文件服务器。建议按角色拆分成不同的job而不是把所有机器塞在同一个job里。- job_name: windows_web static_configs: - targets: [10.0.0.11:9100, 10.0.0.12:9100] labels: role: web - job_name: windows_file static_configs: - targets: [10.0.0.21:9100] labels: role: file这样做的直接好处是告警规则可以按角色差异化配置比如文件服务器磁盘使用率告警阈值可以放宽到90%而数据库服务器80%就要告警。后期如果有动态扩缩容需求还可以接入consul的服务发现让Prometheus自动发现新机器。不过对大多数小团队静态配置就足够用了。4.3 数据留存与资源控制Prometheus默认数据保存15天存储目录是启动目录下的data文件夹。如果觉得时间不够启动参数可以调整.\prometheus.exe --config.fileprometheus.yml --storage.tsdb.retention.time30d --storage.tsdb.retention.size20GBstorage.tsdb.retention.time按时间保留storage.tsdb.retention.size按容量保留两个都设置了取先到者。容量设置在一些机器上比时间更实用毕竟磁盘空间是硬约束。这个参数建议写进服务启动参数里而不是图省事放在配置文件里因为Prometheus的配置文件里没有保留期字段只能在命令行指定。4.4 验证采集链路是否打通Prometheus起来之后在它的Graph界面——就是访问9090端口看到的那个页面——点“Status”下的“Targets”看到所有target状态为UP。接着切到Graph标签页输入一个简单查询比如up{jobwindows}结果应该是1代表目标在线。再输入100 - (avg by (instance) (rate(node_cpu_seconds_total{modeidle}[5m])) * 100)这个查询能算出CPU使用率百分比如果返回数值说明整个采集链路已经通了。到这一步数据源的问题就全部解决了。5. Grafana配置从空白页面到第一个完整看板5.1 首次启动与数据源配置Grafana解压后在bin目录下找到grafana-server.exe启动默认监听3000端口。首次访问界面要求登录默认账号密码都是admin登录后会强制要求改密码。同样建议用NSSM注册成服务参数指向D:\monitoring\grafana\bin\grafana-server.exe工作目录注意要指向D:\monitoring\grafana\bin。登录后左侧菜单进“Connections”再点“Add new connection”搜索Prometheus填连接地址http://localhost:9090注意Grafana如果和Prometheus不在一台机器这里就要填Prometheus所在机器的完整IP。填完后点击“Save test”出现绿色提示说明数据源连接成功。数据源这里有个容易忽略的点Prometheus数据源里有个“Custom HTTP headers”区域如果Prometheus启用了认证需要在这里加Authorization头。没启用认证的就跳过。5.2 直接导入社区维护的Windows监控面板社区面板比自己画高效得多。左侧菜单进入“Dashboards”再点“Import”输入面板ID即可。推荐两个面板名称ID特点Node Exporter Full1860覆盖CPU、内存、磁盘、网络、进程等完整指标Windows Exporter Dashboard10467和node_exporter的Windows采集指标贴合无需修改即可用导入后只需要在面板设置里把数据源切换成自己的Prometheus大部分图表就能直接显示。如果部分图是空的看下面板的变量是否使用了job或instance作为过滤条件和我们实际配置的label值是否匹配。这个是我在实际使用中遇到频率最高的面板显示问题面板本身没问题就是变量里的job名和Prometheus配置里不一致。5.3 从零画一个简单的CPU监控面板有时候社区的现成面板并不能完全满足需求比如我只想看某个进程的CPU占用这时候自己画更灵活。以绘制CPU使用率曲线为例在Dashboard里新建Panel右侧查询编辑器选择数据源Prometheus。输入查询表达式100 - (avg by (instance) (rate(node_cpu_seconds_total{modeidle}[5m])) * 100)把查询类型从“Instant”切换到“Range”右上角时间范围选“Last 15 minutes”。图例里设置显示CPU使用率单位选“percent(0-100)”。保存之后你就有了一块最简单也最核心的监控面板。后续要加内存、磁盘使用率无非就是把表达式换成对应的指标套路完全一样。核心思路是指标名要写对再做必要的数学运算然后在Grafana里选对单位。5.4 看板组织和团队共享监控面板多了以后建议按层级组织一个总的“Windows服务器总览”挂所有机器的关键指标聚合行下面每个角色一个Folder放各自的详细看板。Grafana的Folder功能本身就是干这个的把相同团队的看板放到同一目录并给对应团队账号分配只读权限避免有人误改查询条件导致显示异常。6. 告警来敲门Alertmanager接入与规则示例6.1 告警规则怎么写才不那么吵数据采到、图也画出来了接下来自然就是告警。Prometheus的告警分两步Prometheus根据规则计算是否触发Alertmanager负责把触发的告警以不同方式发出去。创建rules\windows_alerts.yml然后在prometheus.yml里的rule_files加上这个文件groups: - name: windows_host_alerts rules: - alert: WindowsHighCPU expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{modeidle}[5m])) * 100) 90 for: 10m labels: severity: critical annotations: summary: 实例 {{ $labels.instance }} CPU 使用率超过 90% description: CPU使用率已持续10分钟超过90%请检查系统负载这里有个关键词是for: 10m它的意思是持续10分钟都满足条件才触发这能过滤掉大量瞬时毛刺。实际运营中我最深的体会是告警规则一定要加持续时间否则CPU尖峰一分钟内就能把你的告警渠道炸穿。6.2 Alertmanager部署与企业微信/钉钉通知Alertmanager下载解压后目录里的alertmanager.yml负责定义路由和通知方式。以企业微信webhook为例route: group_by: [alertname] group_wait: 10s group_interval: 2m repeat_interval: 1h receiver: wechat receivers: - name: wechat wechat_configs: - send_resolved: true api_url: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?keyYOUR_KEY message: {{ template wechat.default.message . }}配置写好重启Alertmanager再到Prometheus的告警页面——就是9090那个页面里的Alerts标签页——能看到规则评估状态。当告警状态从inactive变到pending再变到firing消息才会真正发出去。钉钉的webhook配置逻辑类似把wechat_configs换成webhook_configs即可payload格式稍有不同。6.3 告警规则的几个经典案例除了CPU使用率Windows监控里还有三个高频告警规则场景值得配置磁盘空间不足。Windows磁盘满导致IIS站点挂掉或数据库写入失败是生产事故最常见的原因之一规则可以参考- alert: WindowsDiskSpaceLow expr: (node_filesystem_size_bytes - node_filesystem_free_bytes) / node_filesystem_size_bytes * 100 85 for: 5m labels: severity: warning服务状态异常。配合Windows服务状态相关指标可以监控关键服务是否在运行状态。节点失联。up{jobwindows} 0这个规则告诉你采集目标挂了是其他一切告警的前提。7. 半个月跑下来我总结的Windows监控踩坑记录7.1 Windows Defender把exe文件隔离了第一次部署时解压出来的node_exporter能被直接运行结果注册成服务重启机器后服务状态变成了“找不到文件”。查了半天发现Windows Defender把二进制文件隔离了因为node_exporter这种读取系统底层信息的工具被Defender的云防护策略打了标签。解决办法是把整个D:\monitoring目录加进Defender的排除列表。操作路径是Windows安全中心 - 病毒和威胁防护 - 管理设置 - 排除项 - 添加排除项 - 文件夹。这是在可信来源下载的官方二进制文件加到白名单没有安全顾虑。7.2 服务以LocalSystem运行但D盘目录权限没给如果按照前面建议用普通账号跑服务一个很容易踩的坑是忘记给NTFS目录授权。Prometheus运行账号如果没有对D:\monitoring\prometheus\data的写权限启动时日志会疯狂报mkdir permission denied但是服务本身可能是Running状态。这个现象非常误导人因为你第一反应是查服务状态看起来都正常往往要摸很久才发现是权限问题。7.3 Grafana查询出现“Data source access denied”Grafana 9之后的版本对组织权限管理更严格如果创建了多个Organization数据源默认只属于第一个Default Organization。新加的用户即便加了Editor角色访问另一个组织的数据源时也可能出现access denied。解决办法是在Grafana的管理后台把数据源在需要的Organization之间共享或者干脆把用户都放在同一个组织下面小团队来说后者简单得多。7.4 告警通知轰炸与静默策略告警配置好后如果忘记设置repeat_intervalAlertmanager会在每次group_interval结束时重复发送同一条告警。有一次磁盘告警我半小时内收到了三十多条企业微信通知。正确做法是设置合适的repeat_interval比如恢复前每1小时重复一次。另外生产环境如果确实需要停机维护提前在Alertmanager的silence页面创建一条静默规则避免维护期间告警刷屏这个功能一般运维容易忽略。8. 落地后的日常演进方向这套监控上线运行以后你会发现它像一个持续生长的基础设施能力边界会随着需求变化不断扩展。就我这段时间的经验来看有几个高性价比的演进方向值得留个心第一node_exporter不止能用在这三件套里它的指标还能被其他工具消费。比如Write-Ahead日志或远程存储组件可以把Prometheus的数据长期归档到对象存储里满足等保或审计对日志留存的更长周期要求。第二Grafana的告警能力其实比很多人理解的要深。它可以不依赖Alertmanager直接把数据源查询结果作为告警条件配置在面板上就可以做点击告警图的交互。这种模式更适合快速验证规则合理性等规则稳定了再固化到Alertmanager统一管理。第三被监控的Windows机器上也可以装telegraf之类的采集器把Windows事件日志或SQL Server等应用指标也收进来和node_exporter的主机指标形成互补。这样一来GrafanaPrometheus这套体系就不只是主机监控工具而是逐步演变成整个Windows基础设施的统一可观测入口。说到底监控这件事回归到本质就是在系统真正出问题之前先用数据画出“常态是什么样”这样一旦出现偏离你才能第一时间发现。这篇文章里的每一步都是我自己从头到尾验证过才写出来的你照着操作大概率能一次跑通。如果中途卡在某个细节回头看看对应的章节尤其是防火墙和目录权限这两块绝大多数坑都出在那里。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进