基于open-faas/faasd的树莓派MQTT订阅函数连接失败求助
问题:OpenFaaS函数无法连接本地Mosquitto MQTT Broker
我们的项目使用激光雷达检测2米范围内的物体,计划在树莓派4上基于open-faas/faasd无服务器框架运行,采用Mosquitto作为MQTT Broker。本地组件运行完全正常:树莓派作为发布端,本地订阅端能成功接收激光雷达数据,但将相同代码部署到OpenFaaS后,出现MQTT连接拒绝错误。
已完成的排查动作:
- 配置Mosquitto监听1883端口(绑定0.0.0.0),开启匿名访问权限
- 使用
mosquitto_sub工具测试连接,结果正常 - 仅当通过OpenFaaS调用订阅函数时,Paho Python客户端出现连接拒绝错误
相关配置文件
Mosquitto配置文件
#place your local configuration file in /etc/mosquitto/conf.d/ # # A full description of the configuration file is at # /usr/share/doc/mosquitto/examples/mosquitto.conf.example pid_file /var/run/mosquitto/mosquitto.pid persistence true persistence_location /var/lib/mosquitto/ log_dest file /var/log/mosquitto/mosquitto.log log_type all # include_dir /etc/mosquitto/conf.d listener 1883 allow_anonymous true # password_file /etc/mosquitto/passwords.txt # acl_file /etc.mosquitto/acl.txt
OpenFaaS YAML配置文件
version: 1.0 provider: name: open-faas gateway: http://localhost:8080 functions: subscriber: lang: python3 handler: ./subscriber image: your-docker-hub-username/subscriber:latest environment: BROKER_ADDRESS: "localhost" TOPIC: "lidar/data"
OpenFaaS handler.py代码
import paho.mqtt.client as mqtt import time broker_address = "localhost" # Use your MQTT broker address topic = "lidar/data" # Use your MQTT topic # This will store the latest message last_msg = None def on_connect(client, userdata, flags, rc): print("Connected with result code "+str(rc)) client.subscribe(topic) def on_message(client, userdata, msg): global last_msg last_msg = msg.payload.decode() print("Received message: " + last_msg) client = mqtt.Client() # Set callback functions client.on_connect = on_connect client.on_message = on_message def handle(req): global last_msg client.connect(broker_address, 1883, 60) client.loop_start() time.sleep(1) # Give the client some time to receive messages client.loop_stop() client.disconnect() return "Last message: " + str(last_msg)
排查建议
修正Broker地址:OpenFaaS函数运行在Docker容器内,容器的
localhost指向自身而非树莓派主机。需将BROKER_ADDRESS改为树莓派的局域网IP(如192.168.x.x):- 更新YAML中的环境变量:
BROKER_ADDRESS: "树莓派局域网IP" - 同时修改handler.py,优先读取环境变量:
broker_address = os.getenv("BROKER_ADDRESS", "localhost")
- 更新YAML中的环境变量:
测试容器网络连通性:进入函数容器,直接测试MQTT连接:
- 执行命令进入容器:
docker exec -it <函数容器ID> /bin/bash - 测试ping树莓派主机,再用
mosquitto_sub -h 树莓派IP -t lidar/data验证MQTT连接
- 执行命令进入容器:
查看Mosquitto日志:检查
/var/log/mosquitto/mosquitto.log,确认是否有来自容器IP的连接请求记录,或是否存在权限、端口相关错误优化MQTT客户端逻辑:当前代码中全局
client变量会被多次重复连接/断开,易引发异常。建议每次调用handle时新建客户端实例,或在函数初始化时完成连接检查防火墙规则:确认树莓派的防火墙(如ufw)允许1883端口的入站连接,确保容器IP能正常访问该端口
内容的提问来源于stack exchange,提问作者Agro20
相关产品推荐
相关产品推荐

