Docker化Spring Boot应用连接外部MQTT服务器失败求助
问题:Docker化Spring MQTT客户端无法连接本地Windows Mosquitto服务
我有一个作为MQTT客户端的Spring应用,本地运行时连接tcp://localhost:1883(Windows服务形式安装的Mosquitto)一切正常,但Docker化后,即使把连接地址换成host.docker.internal:1883,依然报错org.eclipse.paho.client.mqttv3.MqttException: Unable to connect to server。
相关配置
docker-compose配置
mqtt: build: context: MQTT dockerfile: Dockerfile environment: SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/mt_db SPRING_DATASOURCE_USERNAME: root mqttUrl: tcp://host.docker.internal:1883 ports: - 8082:8082 depends_on: - mysql networks: - my-network
主机Mosquitto日志
1690385767: mosquitto version 2.0.15 starting 1690385767: Config loaded from C:\Program Files\mosquitto/mosquitto.conf. 1690385767: Opening ipv6 listen socket on port 1883. 1690385767: Opening ipv4 listen socket on port 1883. 1690385767: mosquitto version 2.0.15 running
mosquitto.conf配置
listener 1883 log_dest file C:\Users\andrea.palermo\Desktop\mosquitto.log log_type all
错误日志
应用启动时错误
mqtt_1 | org.eclipse.paho.client.mqttv3.MqttException: Unable to connect to server mqtt_1 | at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:80) ~[org.eclipse.paho.client.mqttv3-1.2.5.jar!/:na] mqtt_1 | at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:724) ~[org.eclipse.paho.client.mqttv3-1.2.5.jar!/:na] mqtt_1 | at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na] mqtt_1 | Caused by: java.net.ConnectException: Connection refused (Connection refused) mqtt_1 | at java.base/java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:na] mqtt_1 | at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:412) ~[na:na] mqtt_1 | at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:255) ~[na:na] mqtt_1 | at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:237) ~[na:na] mqtt_1 | at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:na] mqtt_1 | at java.base/java.net.Socket.connect(Socket.java:609) ~[na:na] mqtt_1 | at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:74) ~[org.eclipse.paho.client.mqttv3-1.2.5.jar!/:na] mqtt_1 | ... 2 common frames omitted
发布消息时错误
mqtt_1 | org.springframework.messaging.MessageHandlingException: error occurred in message handler [bean 'mqttOutbound'; defined in: 'class path resource [it/mqtt/mqttmanagement/beans/MqttBeans.class]'; from source: 'it.mqtt.mqttmanagement.beans.MqttBeans.mqttOutbound()']; nested exception is org.springframework.messaging.MessagingException: Failed to connect; nested exception is Unable to connect to server (32103) - java.net.ConnectException: Connection refused (Connection refused), failedMessage=GenericMessage [payload={"id_boat":"AAA","latitude":37,"longitude":15}, headers={replyChannel=nullChannel, id=aef51eec-4161-edd5-3c78-9c9df956ca9d, mqtt_topic=info/test, timestamp=1690443018860}] mqtt_1 | at org.springframework.integration.support.utils.IntegrationUtils.wrapInHandlingExceptionIfNecessary(IntegrationUtils.java:191) mqtt_1 | at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:64) mqtt_1 | at org.springframework.integration.handler.ReplyProducingMessageHandlerWrapper.handleRequestMessage(ReplyProducingMessageHandlerWrapper.java:59) mqtt_1 | at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:136) mqtt_1 | at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:55) mqtt_1 | at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:115) mqtt_1 | at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:133) mqtt_1 | at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:106) mqtt_1 | at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:72) mqtt_1 | at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:317) mqtt_1 | at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:272) mqtt_1 | at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:187) mqtt_1 | at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:166) mqtt_1 | at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47) mqtt_1 | at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:109) mqtt_1 | at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:151) mqtt_1 | at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:143) mqtt_1 | at org.springframework.integration.gateway.MessagingGatewaySupport.send(MessagingGatewaySupport.java:428) mqtt_1 | at org.springframework.integration.gateway.GatewayProxyFactoryBean.sendOrSendAndReceive(GatewayProxyFactoryBean.java:657) mqtt_1 | at org.springframework.integration.gateway.GatewayProxyFactoryBean.invokeGatewayMethod(GatewayProxyFactoryBean.java:589) mqtt_1 | at org.springframework.integration.gateway.GatewayProxyFactoryBean.doInvoke(GatewayProxyFactoryBean.java:556) mqtt_1 | at org.springframework.integration.gateway.GatewayProxyFactoryBean.invoke(GatewayProxyFactoryBean.java:545) mqtt_1 | at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) mqtt_1 | at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:220) mqtt_1 | at com.sun.proxy.$Proxy121.senToMqtt(Unknown Source) mqtt_1 | at it.mqtt.mqttmanagement.controller.MqttController.publishOtherBoats(MqttController.java:59) mqtt_1 | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) mqtt_1 | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) mqtt_1 | at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) mqtt_1 | at java.base/java.lang.reflect.Method.invoke(Method.java:566) mqtt_1 | at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84) mqtt_1 | at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) mqtt_1 | at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) mqtt_1 | at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) mqtt_1 | at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) mqtt_1 | at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) mqtt_1 | at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) mqtt_1 | at java.base/java.lang.Thread.run(Thread.java:829) mqtt_1 | Caused by: org.springframework.messaging.MessagingException: Failed to connect; nested exception is Unable to connect to server (32103) - java.net.ConnectException: Connection refused (Connection refused) mqtt_1 | at org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler.checkConnection(MqttPahoMessageHandler.java:227) mqtt_1 | at org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler.publish(MqttPahoMessageHandler.java:237) mqtt_1 | at org.springframework.integration.mqtt.outbound.AbstractMqttMessageHandler.handleMessageInternal(AbstractMqttMessageHandler.java:269) mqtt_1 | at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:55) mqtt_1 | ... 36 more mqtt_1 | Caused by: Unable to connect to server (32103) - java.net.ConnectException: Connection refused (Connection refused) mqtt_1 | at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:80) mqtt_1 | at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:724) mqtt_1 | ... 1 more mqtt_1 | Caused by: java.net.ConnectException: Connection refused (Connection refused) mqtt_1 | at java.base/java.net.PlainSocketImpl.socketConnect(Native Method) mqtt_1 | at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:412) mqtt_1 | at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:255) mqtt_1 | at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:237) mqtt_1 | at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) mqtt_1 | at java.base/java.net.Socket.connect(Socket.java:609) mqtt_1 | at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:74) mqtt_1 | ... 2 more
解决方案
1. 修改Mosquitto监听配置,允许外部连接
当前mosquitto.conf的listener 1883仅监听本地回环地址(127.0.0.1),Docker容器通过host.docker.internal访问时会被拒绝。需明确指定监听所有网卡:
listener 1883 0.0.0.0 log_dest file C:\Users\andrea.palermo\Desktop\mosquitto.log log_type all
0.0.0.0表示监听所有可用网卡,确保Docker容器能通过host.docker.internal连接到Mosquitto。
2. 配置Windows防火墙规则
确保Windows防火墙允许Mosquitto服务的1883端口接收外部连接:
- 打开Windows Defender防火墙高级设置
- 添加入站规则,允许TCP端口1883的连接,或直接允许
mosquitto.exe的网络访问权限
3. 替换连接地址为局域网IP(可选)
若host.docker.internal存在解析问题,可直接使用主机的局域网IP(如192.168.x.x)替换:
mqttUrl: tcp://192.168.1.100:1883
4. 重启Mosquitto服务
修改配置后,在Windows服务管理器中找到“Mosquitto Broker”服务,右键重启以生效。
内容的提问来源于stack exchange,提问作者Andrea Palermo
相关产品推荐
相关产品推荐

