amqplib连接localhost RabbitMQ无响应 无错误及成功日志
问题根因
回调完全不触发的核心原因是:当前主流版本的amqplib的connect方法不支持回调式调用,仅返回Promise。你传入的回调函数会被库直接忽略,自然不会执行内部逻辑,也不会抛出你写在回调分支里的错误。
排查&解决步骤
- 先验证基础连通性:在命令行执行
telnet localhost 5672,确认本地5672端口有RabbitMQ服务正常监听,排除服务未启动、端口占用、防火墙拦截的基础问题。如果telnet连接失败,先把RabbitMQ服务启动正常再测代码逻辑。 - 修正API调用方式:放弃错误的回调写法,用
async/await或者.then()的方式调用amqplib.connect,外层包裹完整的try/catch捕获连接全流程错误,避免错误静默。 - 补全队列声明逻辑:不管是生产还是消费消息,通道创建后必须先断言队列存在,否则首次运行如果队列未创建,收发消息都会直接失败。
- 增加连接状态监听:给连接实例绑定
error、close事件监听,连接意外断开时打印日志、触发自动重连,避免出现无响应的假死状态。
修正后的可运行代码
import amqplib from 'amqplib' import mongoose from 'mongoose' // 补全自身项目的app实例引入,例如express实例 // import app from './app.js' const AMQP_URL = 'amqp://guest:guest@localhost:5672/' const AMQP_QUEUE_NAME = 'email_queue' async function connectRabbitMQ() { console.log('Connecting to rabbit mq...') let connection try { // 用await接收connect返回的Promise,不要传入回调参数 connection = await amqplib.connect(AMQP_URL) console.log('CONNECTED TO RABBIT MQ') // 监听连接异常事件 connection.on('error', (err) => { console.error('RabbitMQ connection error:', err) }) connection.on('close', () => { console.error('RabbitMQ connection closed, will retry after 5s') setTimeout(connectRabbitMQ, 5000) }) // 消费者通道 const channel1 = await connection.createChannel() // 断言队列存在,避免队列不存在导致消费失败 await channel1.assertQueue(AMQP_QUEUE_NAME, { durable: false }) channel1.consume(AMQP_QUEUE_NAME, (msg) => { if (msg !== null) { console.log('Received:', msg.content.toString()); channel1.ack(msg); } else { console.log('Consumer cancelled by server'); } }) // 生产者通道 const channel2 = await connection.createChannel() await channel2.assertQueue(AMQP_QUEUE_NAME, { durable: false }) setInterval(() => { channel2.sendToQueue(AMQP_QUEUE_NAME, Buffer.from('something')) }, 1000) } catch (err) { console.error('Failed to connect RabbitMQ:', err) // 连接失败自动重试 setTimeout(connectRabbitMQ, 5000) if (connection) await connection.close().catch(() => {}) } } function launchServer() { console.log('Launching Server...') console.log('Connecting to MongoDB...') const MONGODB_URI = process.env.MONGODB_URI?.toString() || '' mongoose.connect(MONGODB_URI, {}, (err) => { if (err) { return console.error('Error connecting to Mongo DB !') } console.log('CONNECTED TO MONGO DB') const port = parseInt(process.env.PORT?.toString() || '3000') app.listen(port) console.log('========= SERVER STARTED ========== PORT ' + port) connectRabbitMQ() }) } launchServer()
额外注意点
- 如果用Docker部署RabbitMQ,先确认5672端口已经正确映射到宿主机;RabbitMQ默认的
guest用户仅允许localhost登录,跨机器连接需要提前创建新用户并分配对应vhost权限。 - 如果加了异常捕获后报连接超时错误,优先检查AMQP_URL的账号密码、端口、vhost配置是否正确,RabbitMQ服务端日志会打印拒绝连接的具体原因。
- 不要给支持回调的库方法传入async函数作为回调,这种写法会导致回调内部的异步错误无法被外层捕获,很容易出现静默失败的问题。
内容的提问来源于stack exchange,提问作者iamcrypticcoder
相关产品推荐
相关产品推荐

