尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

小机房不用Zabbix,Ping+TCP+SNMP三层探测实现无人值守监控

发布时间:2026/9/20 20:00:17

资讯中心
01
ARTICLE

小机房不用Zabbix,Ping+TCP+SNMP三层探测实现无人值守监控

小机房不用Zabbix,Ping+TCP+SNMP三层探测实现无人值守监控
凌晨三点值班电话没响但我第二天早上赶到机房才发现核心交换机因为高温自动关机了。柜门一开热浪扑面而来设备面板亮着一排红灯。这种场面做过小机房运维的人多少都经历过。没上Zabbix、没上Prometheus、也没部署任何大型监控平台只是没人盯着而已。后来我用Ping、TCP端口探测和SNMP这三层检查配一个声光告警器把机房改造成了真正意义上能无人值守的现场。这篇文章就把这套方案的完整思路、命令细节和踩坑过程写出来给同样没有预算和人力上大平台的小机房一个直接能抄的作业。1. 先别急着装平台把监控需求拆成三件事1.1 小机房用大型平台的真实成本提到机房监控很多人的第一反应是装Zabbix或者Prometheus解决一切。但说实话对一台核心交换机、两三台服务器、一台防火墙、一台UPS的小机房来说这套东西的维护成本可能比监控对象本身还高。Zabbix要装数据库、配Agent、写模板Prometheus要理解各种Exporter和告警规则Grafana大盘调样式能折腾一整天。而且平台本身还得有人维护机器升级、数据库膨胀、告警规则误报每一个坑都能吃掉你大量时间。对小机房来说核心诉求不是可视化大盘好看而是两件事出问题第一时间知道知道后能快速定位。沿着这个诉求往下拆小机房的监控需求其实就三件事设备到底还活着没有——用Ping探活。设备活着但上面的服务还正常吗——用TCP端口探测。硬件内部有没有隐患比如温度、风扇、CPU——用SNMP采集。三层各管一段互不替代。很多事故的共性规律是先硬件或网络异常然后服务故障最后整机失联。只盯最后一步Ping往往发现的时候已经晚了。1.2 三层探测各解决什么风险我做了一张表把每种探测方式的原理边界理清楚后面写脚本时就是按这个表来分配任务的。探测方式底层原理能发现的问题发现不了的问题PingICMP Echo请求与回显设备关机、断网、网线松动、IP不可达服务假死、端口无监听、硬件温度过高TCP端口探测TCP三次握手能否建立连接服务宕机、端口未监听、进程僵死设备失联时无法区分网络层还是服务层故障SNMP读取设备MIB库中的运行数据CPU负载、内存、温度、风扇转速、接口流量应用层业务异常、慢查询、死锁这套组合下来常见的机器没死但业务坏了网络通但服务挂了设备还在线但内部快烧了三种场景都能覆盖到。下面逐层说具体怎么做。2. Ping探活先用最朴素的工具撑起存活监控2.1 ping命令的常用参数先捋一遍Ping是ICMP协议族里最常用的工具本质是发送Echo Request目标设备回一个Echo Reply。能通只能证明IP层可达但这一层恰恰是判断设备死没死最直接的信号。实际巡检时我不推荐裸敲ping ip就完事因为默认行为是无限ping下去直到你CtrlC。脚本化巡检时几个参数是关键ping -c 3 -W 2 192.168.1.10-c 3只发3个包。巡检场景没必要每个目标ping几百次。-W 2每个包等待2秒超时。如果设备不可达不会傻等很久。-i 1包与包之间的间隔秒数。想控制流量时用。-D每条回显带时间戳做长ping排查丢包时很有用。做持续性的网络质量评估时我一般用长ping配合时间戳ping -D -i 5 192.168.1.10 | tee -a /var/log/ping_history.log这样每5秒打一条带时间戳的回显如果中间出现延迟突然升高或者丢包日志里有据可查。这也是排查ping一个IP显示接收第二个数据其他都是请求超时这类间歇性丢包问题的标准姿势。2.2 整个网段批量探测怎么搞小机房的设备不可能每台手工ping一遍最简单的批量方案是用fping扫一个C段fping -a -g 192.168.1.0/24 2/dev/null-a表示只列出存活的主机-g是扫描整个网段。实测一个24位掩码的网段扫一遍也就两秒不到。没有fping的话用nmap也可以nmap -sn 192.168.1.0/24不过-sn是主机发现不探测端口更适合先摸清楚网段里都有谁在线。日常巡检脚本里我还是推荐自己写个循环控制方式和输出格式更灵活#!/bin/bash # ping_monitor.sh hosts( 192.168.1.10 核心交换机 192.168.1.11 Web服务器 192.168.1.12 防火墙 ) for item in ${hosts[]}; do ip$(echo $item | awk {print $1}) name$(echo $item | awk {print $2}) if ping -c 3 -W 2 $ip /dev/null 21; then echo [$(date %F %T)] $name($ip) 存活 else echo [$(date %F %T)] $name($ip) 不通 fi done我踩过的坑有些服务器管理员出于安全考虑会直接禁掉ICMPLinux上一条iptables -A INPUT -p icmp -j DROP就能让Ping彻底不通但SSH、Web都正常。遇到这种情况Ping结果会有大量误报后面必须靠TCP端口探测去兜底。所以Ping只能算第一层不能当成唯一依据。3. TCP端口探测专治机器活着服务死了3.1 三次握手就是天然的探测探针TCP连接建立靠三次握手客户端发SYN服务端回SYN-ACK客户端再回ACK连接建立。做端口探测的本质就是替真实的业务客户端试一次握手握手能完成说明这个端口上确实有个进程在监听握手失败说明服务要么没起来要么端口被占用或防火墙拦截了。这个思路比Ping高明的地方在于很多服务崩溃的时候机器本身还是好的系统还能正常回ICMP但业务端口已经没人监听了。比如Nginx进程僵死、MySQL崩溃、Tomcat假死这些情况Ping全部显示正常只有去连那个具体端口才会暴露问题。3.2 探端口的三板斧常用的三样工具按场景选# nc 最推荐参数短判定直接 nc -z -w 3 192.168.1.10 80 # telnet 也行但交互式输出不适合脚本 telnet 192.168.1.10 80 # bash 自带 /dev/tcp无额外依赖 timeout 3 bash -c echo /dev/tcp/192.168.1.10/3306 2/dev/null echo 端口开放 || echo 端口不通nc -z是只做连接测试不发数据-w 3是超时3秒。返回值0代表端口可达非0代表失败。脚本里直接判断退出码就行。经常有人问如何ping某个网络的某个端口严格说ping是ICMP没法指定端口。大家真正想要的其实是测试某台机器的某个端口通不通那就是TCP连接测试用上面的nc命令就是标准答案。3.3 TCP connect超时和被拒绝要区分开排查故障时这两个结果指向完全不同的问题很多新手栽在这上面。Connection refused连接被拒绝端口上没有进程监听或者服务进程还没起来。TCP层直接就回了RST包所以报错来得很快。这种情况通常是服务挂了、没启动、或者监听地址配错了。Connect timeout连接超时SYN包发出去了对面完全没回应一直等到超时。这说明网络路径上有东西把包丢了常见原因是防火墙丢包、交换机端口异常、主机负载过高来不及回包。我遇到过最诡异的一次是网卡驱动bug导致入方向的包随机丢失Ping正常但TCP连接就是会定期超时。Connection reset by peer连接被重置握手过程中对方回了RST但原因和refused不一样。常见于服务端的连接队列满了、防火墙主动reset、或者后端程序处理不过来直接关闭连接。用curl访问Web服务时遇到curl: (35) tcp connection reset by peer往往就要往防火墙策略和后端连接数方向排查。3.4 端口探测脚本参考#!/bin/bash # tcp_monitor.sh check_tcp() { local host$1 local port$2 local name$3 if nc -z -w 3 $host $port /dev/null 21; then echo [$(date %F %T)] $name($host:$port) 正常 else echo [$(date %F %T)] $name($host:$port) 异常 fi } check_tcp 192.168.1.10 80 nginx check_tcp 192.168.1.10 443 https check_tcp 192.168.1.11 3306 mysql check_tcp 192.168.1.11 22 ssh小机房的真实经验端口探测的间隔不能太频繁。我之前为了更及时设了每10秒探一次MySQL 3306端口结果被MySQL的connection limit计数逻辑坑了max_connections被一堆探测连接占满差点搞成故障。后来改成1分钟一次同时对每个端口探完立即断开问题才消失。对探活也得当心自己变成故障源。4. SNMP采集温度、风扇、CPU这些内部指标才是硬件倒闭的前兆4.1 SNMP协议要理解到什么程度SNMP全称是简单网络管理协议走UDP 161端口由网管端Manager和设备端Agent组成。设备上开着SNMP服务对外暴露一堆OID节点网管端用snmpget或snmpwalk去读取这些节点就能拿到设备的实时运行数据。版本上v1基本淘汰了v2c是目前兼容性最好的选择v3支持加密和认证但配置复杂。小机房内部网络通常可信用v2c加一个够复杂的community字符串就行。有个地方必须提醒SNMP走的是UDP不是TCP。UDP是无连接的发出去的请求到底是被丢了还是没回复客户端难以区分所以超时重试机制特别重要。snmpget命令里的-t是超时时间-r是重试次数脚本里最好都写上否则设备稍微忙一点就会误报。4.2 常用OID一张表OID是SNMP世界里每个指标的地址搞监控就是跟这些数字打交道。先记住下面这些日常巡检够用了监控项OID说明系统运行时间.1.3.6.1.2.1.1.3.0sysUpTime单位是百分之一秒设备名称.1.3.6.1.2.1.1.5.0sysNameCPU负载.1.3.6.1.2.1.25.3.3.1.2hrProcessorLoad多核设备要遍历内存总容量.1.3.6.1.2.1.25.2.3.1.5hrStorageSize需要结合单位计算接口入流量字节数.1.3.6.1.2.1.2.2.1.10ifInOctets要间隔采样算速率接口出流量字节数.1.3.6.1.2.1.2.2.1.16ifOutOctets具体用起来是这样的# 查看设备运行时间判断有没有偷偷重启过 snmpget -v2c -c public -Ovq 192.168.1.10 .1.3.6.1.2.1.1.3.0 # 遍历所有CPU核心的负载 snmpwalk -v2c -c public -Ovq 192.168.1.10 .1.3.6.1.2.1.25.3.3.1.2CPU负载这块很多设备是多路多核snmpwalk出来的结果是每个逻辑核心的一个值巡检脚本里要取平均值再和阈值比较。4.3 温度和风扇要靠厂商私有OID标准MIB里没有定义机箱温度这个指标每个厂商都有自己的私有OID。比如H3C的设备温度相关节点在hh3cEntityExtTemperature下面Cisco、华为也都各自有一套。怎么找没有捷径就是snmpwalk去遍历厂商OID树然后在输出里搜temperature、fan这些关键字。# 以华为H3C为例遍历整个私有MIB树再过滤温度 snmpwalk -v2c -c public 192.168.1.10 .1.3.6.1.4.1.2011 | grep -i temperature找到之后把温度、风扇转速的OID固化下来写进巡检脚本。风扇转速掉到零或者温度超过70度基本就是硬件故障前兆这种问题Ping和TCP都发现不了只有SNMP能看到。一个重要提醒网上有人问snmp工具将设备重启我想纠正一下SNMP协议本身没有通用的远程重启功能。某些厂商的私有MIB里确实定义了写操作节点可以触发设备重启比如H3C的hh3cEntityExtReboot但生产环境里真不建议靠SNMP去重启设备。这属于高危操作一旦community被猜到别人就能通过SNMP写操作把设备搞挂。监控只是读原则上不要用SNMP做任何写操作。5. 声光告警怎么落地把故障从屏幕上拽到耳朵边5.1 为什么一定要有声光告警监控系统最尴尬的时刻是告警发了没人看。小机房通常没有专门的监控大屏值班人员也不会24小时盯着手机邮件告警和微信告警都可能被忽略。但人对于红灯闪蜂鸣器响这种物理信号是没法忽略的只要人还在机房附近就能第一时间注意到。所以我把声光告警定义为这套方案的最后一公里探测出故障后除了写日志还要物理地拉响警报。目标很简单——让故障从屏幕上跳到人的感官里。5.2 硬件选型的三条路线每条路线都有适用场景我列个对比方案成本化程度可靠性适合场景USB继电器 24V声光报警灯低继电器模块几十块灯一百多需要动手接线中等USB依赖服务器稳定机房里有闲置Linux服务器树莓派GPIO 蜂鸣器/LED低需要简单Python编程中高树莓派本身不能坏想顺便做其他自动化场景商业网络声光报警器中等偏高无需改装配IP直接HTTP触发高设备独立运行预算允许、追求省事我自己用的是第一种。主监控机上插一个USB继电器模块继电器输出端串到24V声光报警灯的供电回路里。正常时继电器断开灯不响不闪触发时继电器吸合报警灯通电红闪加蜂鸣器齐响动静相当大。5.3 触发脚本的核心是去抖声光告警最忌讳的是一有抖动就响。Ping丢一个包就报警可能一晚上响十几次第二天就没人把它当回事了——这就是告警疲劳。我的触发脚本分两段一个trigger_alarm.sh负责真正操作继电器一个上面说的巡检脚本负责判断要不要调它。#!/bin/bash # /usr/local/bin/trigger_alarm.sh on|off # 通过USB继电器厂商提供的命令行工具或者自己写的一段python控制继电器通道 case $1 in on) python3 /usr/local/bin/usb_relay.py --channel 1 --on echo [$(date %F %T)] ALARM_ON /var/log/room_alarm.log ;; off) python3 /usr/local/bin/usb_relay.py --channel 1 --off echo [$(date %F %T)] ALARM_OFF /var/log/room_alarm.log ;; esac状态机逻辑放在巡检脚本里核心就一句话连续3次检查失败才拉响连续2次成功才解除。这样瞬时丢包、设备重启瞬间的抖动都不会触发误报而真正的持续故障会在3分钟内被拉响。如果有商业网络报警器on和off就变成两个HTTP请求逻辑完全一样curl -s http://192.168.1.20/api/alarm?stateon curl -s http://192.168.1.20/api/alarm?stateoff5.4 别忘了维护模式巡检脚本跑久了你会遇到一个很实际的问题白天要动设备拔网线、重启服务、换硬件时声光报警器会疯狂地响。所以最终方案里必须加一个维护模式开关。最简单的实现是放一个维护标记文件巡检脚本开头检查一下if [ -f /var/run/room_maintenance ]; then echo [$(date %F %T)] 维护模式跳过告警 /var/log/room_guard.log exit 0 fi进维护的时候touch /var/run/room_maintenance维护完rm -f /var/run/room_maintenance。这个细节看着不起眼实际用下来能省掉大量狼来了式的误报强烈建议加上。6. 三层合一一个巡检脚本加cron就能撑起无人值守6.1 脚本的整体执行流程把前面三层的逻辑合并到一个脚本里执行顺序是这样的先跑Ping层检查核心设备和服务器是否在线。再跑TCP层检查关键业务端口是否正常监听。最后跑SNMP层检查CPU负载、温度和风扇状态。每层检查不通过失败计数加1。对比历史失败计数判定是持续故障还是瞬时抖动。持续故障就触发声光告警拉响恢复后触发解除。所有动作写日志方便事后排查。6.2 完整参考脚本下面这个脚本我用了很长时间逻辑清晰可以直接拿过去改#!/bin/bash # /usr/local/bin/room_guard.sh # 小机房三层探测巡检脚本 SELF_LOG/var/log/room_guard.log STATE_FILE/tmp/room_guard_fail_count THRESHOLD3 ALARM_ON_URLhttp://127.0.0.1:8080/alarm?stateon ALARM_OFF_URLhttp://127.0.0.1:8080/alarm?stateoff now() { date %F %T; } log() { echo [$(now)] $* $SELF_LOG; } fail_count0 # 第1层Ping探活 for host in 192.168.1.10 192.168.1.11 192.168.1.12; do if ! ping -c 3 -W 1 $host /dev/null 21; then log PING_FAIL $host fail_count$((fail_count 1)) fi done # 第2层TCP端口探测 if ! nc -z -w 3 192.168.1.10 80 /dev/null 21; then log TCP_FAIL 192.168.1.10:80 fail_count$((fail_count 1)) fi if ! nc -z -w 3 192.168.1.11 3306 /dev/null 21; then log TCP_FAIL 192.168.1.11:3306 fail_count$((fail_count 1)) fi # 第3层SNMP检查CPU负载 cpu$(snmpget -v2c -c public -Ovq -t 2 -r 1 192.168.1.10 .1.3.6.1.2.1.25.3.3.1.2.1 2/dev/null) if [ -z $cpu ] || [ $cpu -gt 90 ] 2/dev/null; then log SNMP_CPU_FAIL 192.168.1.10 cpu$cpu fail_count$((fail_count 1)) fi # 判定与告警去抖 last_count$(cat $STATE_FILE 2/dev/null || echo 0) if [ $fail_count -ge $THRESHOLD ]; then if [ $last_count -lt $THRESHOLD ]; then log ALARM_ON last$last_count now$fail_count curl -s $ALARM_ON_URL /dev/null fi elif [ $fail_count -eq 0 ]; then if [ $last_count -ge $THRESHOLD ]; then log ALARM_OFF curl -s $ALARM_OFF_URL /dev/null fi fi echo $fail_count $STATE_FILE log CHECK_DONE fail_count$fail_count判断逻辑里的关键点是last_count和THRESHOLD的对比。只有上一次计数已经达到告警阈值、这次全部恢复正常时才发解除信号避免每次检查都重复触发告警。这个状态变化才通知的设计比每次检查失败都响一声要优雅得多。6.3 cron定时任务和历史日志脚本写好后挂到cron里每分钟执行一次* * * * * /usr/local/bin/room_guard.sh /dev/null 21为什么设1分钟而不是10秒一是探活本身要时间三层全跑下来大概十几秒太频繁会和业务抢资源二是小机房的故障响应需求1分钟内完全够用。真要追求秒级那是生产级大平台的活跟咱们这套轻量方案的目标不符。日志查看也简单# 看最新的巡检记录 tail -n 50 /var/log/room_guard.log # 看什么时候报过警 grep ALARM_ON /var/log/room_guard.log实际运行中这套脚本每月的日志量也就不到1MB完全不需要考虑日志轮转的问题。7. 上线后真实踩过的一些坑7.1 跨主机的虚拟机互ping不通我们监控对象里包含几台虚拟机一开始出现最多的误报就是虚拟机Ping不通。排查下来大部分是虚拟网络的问题和物理网络无关。同一台宿主机上的跨虚拟机ping不通先查虚拟交换机的端口组配置和VLAN划分不同宿主机之间的虚拟机ping不通查宿主机之间的trunk链路以及虚拟机自身的防火墙。另外VMware的默认安全策略里有个伪造传输和MAC地址更改的开关某些场景下也坑过我一回。排查顺序建议目标虚拟机内的防火墙规则 → 虚拟交换机端口组 → 宿主机网络 → 物理链路。别一上来就怪网络。7.2 ping显示接收第二个数据其他都是请求超时这是搜索热词里出现的典型症状ping同一台机器4个包里只有第2个有回显其他全部请求超时。这种间歇性丢包比完全不通更难查因为当你手忙脚乱去ping的时候可能又全通了。我处理过的一个真实案例最后定位到是交换机端口的双工模式不匹配。对端网卡自协商成了半双工交换机端口固定全双工导致高负载下丢包率飙升。另一个案例是内网某台机器上有环回广播风暴把交换机的CPU打满表现也是间歇性丢包。排查这类问题最直接的办法就是前面说的长ping加时间戳看丢包规律是否和业务高峰重合同时查交换机端口的input errors和output errors计数# 看端口错误计数如果CRC错误猛增大概率是物理层问题 snmpwalk -v2c -c public 192.168.1.10 .1.3.6.1.2.1.2.2.1.147.3 TCP connect超时与connection reset的判据别搞反我在前文第3节提过这两个的区别这里再展开说一下实战判断。Connection timed out是SYN包石沉大海。可能原因包括防火墙丢包、主机网卡异常、ARP解析失败。排查时从三层逐层往上看先ping通了说明网络层通再查ARP表最后查防火墙规则。Connection reset by peer是对方回了RST。如果你探测的是自己写的服务先看连接队列是不是满了如果是Web服务看后端应用有没有崩溃如果是对外访问第三方服务优先怀疑中间的网络设备做了RST拦截。我遇到过Tomat的rmi tcp connection线程堆积导致整个端口假死的案例表象就是偶发reset不频繁但很烦人。这类问题靠端口探测只能发现问题定位还得看应用日志和线程堆栈。7.4 防火墙把ICMP全禁掉造成的误报前面提过有些服务器的管理员出于安全考虑会禁掉ICMP。我的建议是小机房内部互相监控的设备把ICMP放开。内网的可信环境里一个Ping请求带来的安全风险微乎其微但对监控的友好度提升是巨大的。如果实在放不开那就必须在监控脚本里给该设备配置跳过Ping层只做TCP层检查否则天天误报。更隐蔽的一种情况是Windows防火墙默认禁Ping但SSH、RDP都正常。这种最容易让人怀疑设备坏了其实人家活得好好的。遇到Ping不通但业务正常的结果第一反应应该是查防火墙策略而不是换网线。7.5 SNMP的community、版本和超时要一致SNMP写进巡检脚本最常遇到三类问题Community字符串不对脚本里配的public设备上实际改成了别的snmpget直接返回Timeout。版本不匹配设备只开了v3脚本用v2c去读必然失败。UDP超时重试没配设备负载高的时候UDP响应慢了几百毫秒snmpget默认超时太短就会误报。前两类靠核对配置解决第三类靠-t 2 -r 2这种超时和重试参数解决。我的经验是SNMP类监控的误报率比Ping和TCP都要高所以SNMP层失败计数要单独加权比如两次连续失败才计入总失败数避免一台设备SNMP慢一点就把整个机房声光报警拉响。7.6 误报与漏报之间怎么取舍无人值守监控最后绕不开一个哲学问题宁可误报还是宁可漏报我的答案是分场景。对机房温度、核心交换机这类出问题就是大事的关键指标宁可误报哪怕半夜被叫起来一趟也比第二天设备烧了强。对普通服务器上的普通服务端口阈值就定得宽松些连续3次失败再报容忍一定程度的抖动。实际操作里我就是靠THRESHOLD这个变量来调的。冬天天气冷设备温度普遍低阈值调低一点没关系夏天高温天温度阈值就得留足余量否则空调一停报警器能把你折腾一晚上。这个度只有在自己机房里跑一段时间才能摸准。写在最后这套方案已经在我的机房里连续跑了半年多真实抓过三次故障。一次是交换机风扇停转导致温度攀升到75度SNMP先发现一次是防火墙CPU被打满导致TCP连接大范围超时端口探测先报警还有一次是机房空调跳闸温度数据异常直接拉响声光报警。每次都是警报先响我才去看日志定位。这套东西确实不漂亮没有炫酷的大屏也没有复杂的告警收敛算法但它稳定、够用、不占人力。对小机房来说这比一套需要专职维护的监控平台实在得多。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。