使用Node.js的AWS SDK时,SQS队列无飞行中消息问题排查
排查Node.js AWS SDK操作SQS后无飞行中消息的问题
看起来你遇到的问题是用Node.js的AWS SDK往SQS发消息,但控制台里看不到飞行中的消息。我来帮你一步步排查可能的原因,结合你的代码片段来分析:
1. 先确认消息是否真的发送成功了
你的代码里没有处理sendMessage的返回结果,也没捕获错误,很可能消息发送失败了但你没察觉。先给代码加上日志和错误捕获,这样能直接看到发送状态:
const AWS = require('aws-sdk'); AWS.config.update({ accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY }); const sqs = new AWS.SQS({ region: 'us-east-1' }); return Promise.map(utxos, (utxo) => { // 先把消息体完整序列化,避免截断或语法错误 const messageBody = JSON.stringify({ txid: utxo.txid, CurrencyId: CurrencyId, address: utxo.address }); console.log('准备发送消息:', { QueueUrl: process.env.SQS_URL, MessageBody: messageBody }); return sqs.sendMessage({ QueueUrl: process.env.SQS_URL, MessageBody: messageBody }).promise() // 用promise形式更贴合Promise.map .then(sendResult => { console.log(`消息发送成功,MessageId: ${sendResult.MessageId}`); return sendResult; }) .catch(sendErr => { console.error(`发送单个消息失败: ${sendErr.message}`, sendErr); throw sendErr; // 抛出错误让Promise.map知道这个任务失败了 }); }) .catch(batchErr => { console.error('批量发送消息整体失败:', batchErr); });
运行修改后的代码,如果你看到MessageId打印出来,说明消息确实发送成功了;如果看到错误日志,根据错误信息就能定位问题:
InvalidClientTokenId:AWS凭证不正确AccessDenied:当前凭证没有sqs:SendMessage权限QueueDoesNotExist:队列URL错误或者区域不匹配
2. 检查消息体的序列化是否正确
你的代码里MessageBody用了JSON.stringify,但要注意几个点:
- 确保
CurrencyId变量是已定义的(你代码里的截断Currenc...会不会是拼写错误?比如少了最后一个y?) - 如果
utxo里有循环引用或者不可序列化的内容,JSON.stringify会抛出错误,这时候消息也发不出去
3. 验证队列配置是否匹配
- 确认
process.env.SQS_URL的队列确实在us-east-1区域,因为你初始化SQS客户端时指定了这个区域,跨区域的队列是无法访问的 - 检查队列URL是否完整正确,比如有没有多余的空格或者拼写错误
4. 排查消费者的干扰
如果你的SQS队列有消费者在运行,可能消息刚发送就被立即接收了,飞行中状态持续的时间极短,所以你在控制台刷新的时候看不到。可以临时停止所有消费者,再发送消息试试,这时候如果消息出现在飞行中列表,就说明是消费者的问题。
5. 控制并发发送的数量
Promise.map默认是无限制并发发送消息的,如果utxos的数量很大,很容易触发AWS的限流机制(Throttling),导致部分消息发送失败。可以给Promise.map加上并发限制,比如:
Promise.map(utxos, (utxo) => { /* ... */ }, { concurrency: 5 })
根据你的队列并发限制调整这个数字,避免被限流。
6. 检查IAM权限
确保你的AWS凭证对应的IAM用户/角色有sqs:SendMessage权限,对应的IAM策略应该类似:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sqs:SendMessage", "Resource": "arn:aws:sqs:us-east-1:你的账号ID:你的队列名称" } ] }
按上面的步骤一步步排查,应该能找到问题所在。
内容的提问来源于stack exchange,提问作者Shamoon
相关产品推荐
相关产品推荐

