You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Python MQTT脚本shell运行正常systemd自启收不到Mosquitto数据

MQTT接收脚本配置systemd自启后无法接收消息的常见原因及解决方案

核心代码逻辑缺陷

  • 订阅时机错误:当前代码首次执行订阅逻辑sub_topics()需要等待启动后30秒,且未在MQTT连接成功的回调on_connect中执行订阅。paho-mqtt客户端若发生断连重连,非持久会话下所有已订阅主题会失效,必须在每次连接成功后重新订阅,否则会出现断连后再也收不到消息的问题。
  • 未配置自动重连:代码未开启MQTT客户端自动重连逻辑,若启动初期网络波动、broker未完全就绪导致连接断开,客户端不会主动重连,也无法接收消息。

systemd配置问题

  • 执行用户不匹配:手动运行脚本时通常使用树莓派默认pi用户,systemd服务默认以root用户执行。若脚本的MQTT用户名密码、数据库配置是从当前用户的私有配置文件、环境变量读取,root用户无法读取对应配置,会导致连接认证失败,无法订阅主题。
  • 工作目录未配置:若脚本使用相对路径读取配置文件,systemd默认工作目录为/,会导致配置文件读取失败,配置项加载错误。
  • 日志缓冲导致误判:Python非终端运行时默认开启全缓冲,print输出的内容不会实时写入systemd日志,会导致你误以为脚本未收到消息,实际是日志未刷新。
  • 未配置异常重启:代码中所有异常捕获后都会直接退出进程,若启动初期数据库、MQTT broker未完全就绪导致脚本启动失败,未配置Restart策略的话脚本会停止运行,不会自动恢复。
  • 启动依赖不充分:仅配置After=mosquitto.service仅保证服务启动顺序,不保证mosquitto已完成端口监听、可以正常接受连接,启动时可能出现脚本先连接MQTT失败退出的问题。

修复方案

  1. 调整MQTT逻辑:
    • 在on_connect回调中添加订阅逻辑,确保每次连接成功后自动订阅所有主题,保留原30秒刷新订阅的逻辑用于同步数据库中新增的设备ID
    • 添加自动重连配置,创建客户端后新增clienteMQTT.reconnect_delay_set(min_delay=1, max_delay=128)
    • 在on_connect中打印返回码rc,确认连接状态,非0返回码对应连接错误可直接定位问题
  2. 修正systemd单元配置,参考配置如下:
    [Unit]
    Description=MQTT Data Receiver
    After=mosquitto.service mariadb.service dhcpcd.service wpa_supplicant.service
    
    [Service]
    User=pi
    Group=pi
    WorkingDirectory=/path/to/your/script/directory
    Environment="PYTHONUNBUFFERED=1"
    ExecStart=/usr/bin/python3 /path/to/your/script/receiver.py
    Restart=always
    RestartSec=5
    ExecStartPre=/bin/sleep 10
    
    [Install]
    WantedBy=multi-user.target
    
  3. 检查配置加载逻辑:所有敏感配置(用户名、密码、端口等)优先使用绝对路径读取配置文件,避免用户权限导致的读取失败。

内容的提问来源于stack exchange,提问作者MauroDiamantino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 16:15:03