智能 PDU 的 SNMP / MQTT / SSH 三种接入方式对比与选型建议

0 阅读6分钟

智能 PDU 的 SNMP / MQTT / SSH 三种接入方式对比与选型建议

智能 PDU 的"智能"二字,最后都要落到一句话上:数据怎么出来,命令怎么进去。

目前主流的接入方式有三种:SNMP、MQTT、SSH。它们不是迭代关系(不是谁替代谁),而是面向不同运维体系的三条路。这篇从协议机制、部署成本、适配场景三个维度做对比,并给出可运行的代码示例。


一、三种方式的定位差异

维度SNMPMQTTSSH
模型轮询 + Trap发布/订阅交互式命令行
传输UDP 161/162TCP 1883(TLS 8883)TCP 22
数据格式OID + ASN.1自定义(通常 JSON)文本
实时性取决于轮询周期准实时(推送)交互式
平台依赖需 NMS / 网管平台需 MQTT Broker无需中间件
批量运维适合采集适合采集 + 事件适合批量操作
历史遗留系统兼容性最好较新通用

一句话定位:

  • SNMP:传统动环/网管系统的通用语言,接入现成平台最省事
  • MQTT:云化和物联网场景的首选,轻量、穿透性好
  • SSH:批量运维和自动化脚本的主力,做"操作"而非"采集"

二、SNMP:老牌但要注意版本

关键点

  • v1/v2c 用 community string 做认证,明文传输,内网尚可,跨公网不推荐
  • v3 支持认证与加密(authPriv),安全性足够,但配置复杂
  • 数据采集靠 GET / GETNEXT / WALK 遍历 OID
  • 告警靠 Trap(162 端口主动上报)

PDU 常见的采集项

厂商通常用私有 OID 分支(.1.3.6.1.4.1.xxx),标准 MIB(如 UPS MIB .1.3.6.1.2.1.33)覆盖有限。实测中常见的采集点:

总输入电压 / 电流 / 有功功率 / 电能
支路电流(每路插座)
开关状态(每路)
温度 / 湿度(若带传感器)
告警状态字

代码示例:pysnmp 批量采集

from pysnmp.hlapi import *

def snmp_get(host, community, oid, port=161, timeout=3, retries=1):
    iterator = getCmd(
        SnmpEngine(),
        CommunityData(community, mpModel=0),   # 0 = v1, 1 = v2c
        UdpTransportTarget((host, port), timeout=timeout, retries=retries),
        ContextData(),
        ObjectType(ObjectIdentity(oid))
    )
    errorIndication, errorStatus, errorIndex, varBinds = next(iterator)
    if errorIndication:
        return None, str(errorIndication)
    if errorStatus:
        return None, errorStatus.prettyPrint()
    for name, val in varBinds:
        return str(name), val.prettyPrint()

# 示例:读总电流
oid, val = snmp_get("10.0.0.21", "public", "1.3.6.1.4.1.99999.1.1.3.0")
print(oid, val)

注意事项

  1. 轮询周期别设太短。SNMP 走 UDP,高频轮询会放大丢包影响。一般 30–60s 采集一次足够,功率类可以 10s。
  2. WALK 很贵。整表遍历在设备数量多时是性能杀手,尽量用精确 OID 的 GET。
  3. v2c 的 community 建议至少改成非 public,并限制源 IP。

三、MQTT:轻量、适合云化

为什么 PDU 场景适合 MQTT

  • PDU 数量多、单点数据量小 —— 正对 MQTT 的设计场景
  • 走 TCP + 长连接,穿 NAT 比 SNMP 容易
  • QoS 分级,关键告警可以用 QoS 1(至少一次)
  • Payload 通常是 JSON,解析成本低

Topic 设计建议

一个实用的层次结构:

pdu/{site}/{room}/{rack}/{pdu_id}/telemetry    # 遥测数据,周期性发布
pdu/{site}/{room}/{rack}/{pdu_id}/alarm        # 告警,事件触发
pdu/{site}/{room}/{rack}/{pdu_id}/state        # 开关状态(LWT 用)
pdu/{site}/{room}/{rack}/{pdu_id}/cmd          # 下行指令(订阅)

要点:

  • 遥测与告警分 topic,订阅方可以只关心告警
  • 用 LWT(Last Will and Testament) 做掉线检测:设备异常断线时 Broker 自动发布离线消息
  • 下行指令单独一个 topic,配合 retain = false 避免重连时误执行

代码示例:paho-mqtt 订阅与解析

import json
import paho.mqtt.client as mqtt

def on_connect(client, userdata, flags, rc):
    print("connected rc=", rc)
    client.subscribe("pdu/+/+/+/+/telemetry", qos=1)
    client.subscribe("pdu/+/+/+/+/alarm", qos=1)

def on_message(client, userdata, msg):
    try:
        payload = json.loads(msg.payload.decode("utf-8"))
    except Exception:
        return
    parts = msg.topic.split("/")
    pdu_id = parts[4]
    kind = parts[-1]
    if kind == "alarm":
        print(f"[ALARM] {pdu_id} -> {payload}")
    else:
        # 写入时序库,如 InfluxDB / TDengine
        print(f"[DATA ] {pdu_id} power={payload.get('power_w')}W")

c = mqtt.Client(client_id="collector-01")
c.username_pw_set("collector", "secret")
c.on_connect = on_connect
c.on_message = on_message
c.connect("broker.internal", 1883, keepalive=60)
c.loop_forever()

注意事项

  1. QoS 不是越高越好。QoS 2(恰好一次)开销大,遥测数据用 QoS 0/1 即可,丢一两个点不影响趋势。
  2. Broker 要做鉴权。默认匿名访问的 Broker 暴露在内网里是常见的风险点。
  3. 时钟对齐。设备端 timestamp 不可信时,采集侧要打自己的时间戳。

四、SSH:做操作,不做采集

SSH 的价值不在采集(解析文本输出太脆弱),而在批量操作:批量开关插座、批量改配置、批量升级固件。

典型用法

import paramiko

def run(host, user, key_path, cmd, timeout=10):
    cli = paramiko.SSHClient()
    cli.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    cli.connect(host, username=user, key_filename=key_path, timeout=timeout)
    stdin, stdout, stderr = cli.exec_command(cmd, timeout=timeout)
    out = stdout.read().decode("utf-8", "ignore")
    err = stderr.read().decode("utf-8", "ignore")
    cli.close()
    return out, err

out, err = run("10.0.0.21", "ops", r"C:\keys\pdu_rsa", "show power")
print(out)

注意事项

  1. 用密钥不要用密码,且私钥要加密保存
  2. 禁用 SSHv1,算法优先 ed25519 / rsa-3072
  3. 输出解析是脆弱点。固件升级可能改变输出格式,脚本要有容错和版本判断
  4. 并发要限流。同时对几百台 PDU 发起 SSH 连接,容易把管理网打满

五、选型建议

按场景给结论:

场景首选理由
已有 Zabbix / Nagios / 动环平台SNMP模板现成,接入成本最低
新建云平台 / 边缘采集MQTT轻量、易扩展、穿透性好
批量运维、自动化操作SSH命令行最直接
无人值守站点、弱网环境MQTT断线重连机制成熟
需要严格审计与加密SNMPv3 或 SSHv2c 明文,不适合

实践中通常是组合使用:SNMP 或 MQTT 负责采集与告警,SSH 负责偶尔的批量操作。不要试图用一个协议解决所有问题。


六、一个容易忽略的点:计量精度

无论用哪种协议采集,数据源头的精度决定了上层分析的价值。

PDU 的计量精度常见在 ±1% 到 ±3% 之间。如果你的目标是做容量规划或 PUE 测算,建议要求 ±1% 这个量级。理由:

  • PUE 是比值,分子分母各有误差会叠加
  • 精度低的数据无法支撑"某机柜是否还有余量"这类决策

采集协议本身不产生误差,但如果协议侧做了取整(比如功率只上报整数瓦),等于把精度白白丢掉。选型时确认上报值的小数位和单位。


总结

采集为主 + 已有网管平台   → SNMP
采集为主 + 云化/边缘       → MQTT
操作为主 + 批量脚本        → SSH
生产环境                   → 采集与操作分离,两种协议并用

本文协议参数依据 SNMP、MQTT OASIS 规范及通用运维实践整理。代码示例为简化演示,生产环境请补充异常处理、重试与日志。


关于 IDCPDU:IDCPDU 是宁波盛邦通信设备有限公司旗下品牌,专注智能 PDU 研发与制造。公司 2014 年成立,核心团队拥有 25 年行业经验,现有员工 70 人,生产基地 21,000㎡,年产 PDU 30 万台,通过 ISO 9001 认证,产品取得 CCC、CE、GS、EMC 认证。