Spring Boot连接Docker中RabbitMQ时遭遇连接拒绝异常
Spring Boot生产者无法连接Docker部署的RabbitMQ:连接拒绝问题排查
问题描述
在localhost:8081运行Spring Boot生产者服务,尝试向Docker部署的rabbitmq:3.12.2-management实例发送消息时,出现连接拒绝异常。已尝试将spring.rabbitmq.host修改为localhost或172.17.0.1,参考相关问题后仍未解决。
代码与配置信息
RabbitMQConfig.java
package com.akshay.springbootrabbitmq.config; import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.Queue; import org.springframework.amqp.core.TopicExchange; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RabbitMQConfig { @Value("${rabbitmq.queue.name}") private String queue; @Value("${rabbitmq.exchange.name}") private String exchange; @Value("${rabbitmq.routing.key}") private String routingKey; @Bean public Queue queue() { return new Queue(queue); } @Bean public TopicExchange exchange() { return new TopicExchange(exchange); } @Bean public Binding bind() { return BindingBuilder.bind(queue()) .to(exchange()) .with(routingKey); } }
RabbitMQProducer.java
package com.akshay.springbootrabbitmq.publisher; import org.springframework.amqp.AmqpException; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @Service public class RabbitMQProducer { @Value("${rabbitmq.exchange.name}") private String exchange; @Value("${rabbitmq.routing.key}") private String routingKey; private RabbitTemplate rabbitTemplate; @Autowired public RabbitMQProducer(RabbitTemplate rabbitTemplate) { this.rabbitTemplate = rabbitTemplate; } public void sendMessage(String message) { System.out.println("Sending message - "+message+" to the exchange named - "+exchange); try { rabbitTemplate.convertAndSend(exchange, routingKey, message); }catch(AmqpException ex) { ex.printStackTrace(); } } }
MessageController.java
package com.akshay.springbootrabbitmq.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.akshay.springbootrabbitmq.publisher.RabbitMQProducer; @RestController public class MessageController { private RabbitMQProducer producer; @Autowired public MessageController(RabbitMQProducer producer) { this.producer = producer; } @GetMapping("/api/publish") public ResponseEntity<String> sendMessage(@RequestParam("msg") String message){ producer.sendMessage(message); return ResponseEntity.ok("Message sent to RabbitMQ"); } }
application.properties
server.port=8081 spring.rabbitmq.host=172.17.0.1 spring.rabbitmq.port=5672 rabbitmq.queue.name=JavaTest rabbitmq.exchange.name=JavaExchange rabbitmq.routing.key=Java_routing_key
Docker相关信息
容器信息
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5fa2a5be9ed9 rabbitmq:3.12.2-management "docker-entrypoint.s…" 13 seconds ago Up 12 seconds 4369/tcp, 5671-5672/tcp, 15691-15692/tcp, 25672/tcp suspicious_chatelet
网络信息
[ { "Name": "bridge", "Id": "21397db4b92db2ecc181c502b4db27d673614a1c1ae07fbf0d0751ab1e70cd85", "Created": "2023-08-08T12:18:21.6715506Z", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "5fa2a5be9ed9aff148d2318d4dfc5e10cc4581c0a6aac702ff477f6268e65c8a": { "Name": "suspicious_chatelet", "EndpointID": "54b34aa3f809b91d4e53de47c743ef1cad4d31e30a6e758fab31aed0bae11839", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" } }, "Options": { "com.docker.network.bridge.default_bridge": "true", "com.docker.network.bridge.enable_icc": "true", "com.docker.network.bridge.enable_ip_masquerade": "true", "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0", "com.docker.network.bridge.name": "docker0", "com.docker.network.driver.mtu": "1500" }, "Labels": {} } ]
异常日志
2023-08-08T18:53:40.395+05:30 INFO 11108 --- [nio-8081-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' 2023-08-08T18:53:40.395+05:30 INFO 11108 --- [nio-8081-exec-2] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' 2023-08-08T18:53:40.397+05:30 INFO 11108 --- [nio-8081-exec-2] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms Sending message - "This is from Postman" to the exchange named - JavaExchange 2023-08-08T18:53:40.453+05:30 INFO 11108 --- [nio-8081-exec-2] o.s.a.r.c.CachingConnectionFactory : Attempting to connect to: [localhost:5672] org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused: no further information at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:61) at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:594) at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:687) at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.createConnection(ConnectionFactoryUtils.java:257) at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:2225) at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:2198) at org.springframework.amqp.rabbit.core.RabbitTemplate.send(RabbitTemplate.java:1119) at org.springframework.amqp.rabbit.core.RabbitTemplate.convertAndSend(RabbitTemplate.java:1182) at org.springframework.amqp.rabbit.core.RabbitTemplate.convertAndSend(RabbitTemplate.java:1175) at com.akshay.springbootrabbitmq.publisher.RabbitMQProducer.sendMessage(RabbitMQProducer.java:28) at com.akshay.springbootrabbitmq.controller.MessageController.sendMessage(MessageController.java:23)
排查与解决步骤
补全Docker端口映射
当前容器未将5672端口映射到宿主机,导致外部无法访问。停止现有容器后,用以下命令重新启动:docker stop suspicious_chatelet docker rm suspicious_chatelet docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3.12.2-management映射后,Spring Boot服务可以通过
localhost:5672或172.17.0.1:5672连接RabbitMQ。确认配置文件生效
异常日志显示程序仍在尝试连接localhost:5672,但配置文件中是172.17.0.1,需确认:application.properties放在src/main/resources目录下- 重启Spring Boot服务,确保配置加载
- 可在
RabbitMQProducer中添加代码打印配置值,验证是否正确读取:@Value("${spring.rabbitmq.host}") private String rabbitHost; @Value("${spring.rabbitmq.port}") private int rabbitPort; public void sendMessage(String message) { System.out.println("Connecting to RabbitMQ at " + rabbitHost + ":" + rabbitPort); // 原有逻辑... }
验证网络连通性
在宿主机执行命令测试容器端口是否可达:nc -zv 172.17.0.2 5672如果不通,检查Docker防火墙规则,确保bridge网络未被拦截。
检查RabbitMQ服务状态
进入容器查看服务是否正常运行:docker exec -it rabbitmq rabbitmqctl status若服务异常,查看容器日志排查启动问题:
docker logs rabbitmq配置RabbitMQ用户权限
默认guest用户仅允许localhost访问,若使用该用户连接外部,需修改权限:- 访问管理控制台
http://localhost:15672,登录账号guest/guest - 进入
Admin->Users-> 点击guest-> 修改Permissions为/.*,允许所有虚拟主机访问 - 在
application.properties中添加用户名密码:spring.rabbitmq.username=guest spring.rabbitmq.password=guest
- 访问管理控制台
内容的提问来源于stack exchange,提问作者Akshay
相关产品推荐
相关产品推荐

