AWS lambda 发送 SNS“成功”但未实际发送消息

Posted

技术标签:

【中文标题】AWS lambda 发送 SNS“成功”但未实际发送消息【英文标题】:AWS lambda to send SNS "succeeds" but message not actually sent 【发布时间】:2016-03-16 07:34:32 【问题描述】:

我编写了一个 AWS lambda 函数,用于在上传 S3 对象时发送文本消息。我已经确认订阅,我可以收到从 SNS 控制台发送的测试消息。

当我测试 lambda 时,所有日志都说方法成功但没有儿子消息到达。这是函数(大部分只是示例模板,但为了安全起见,我在这篇文章中更改了我的主题)。任何要测试/尝试下一步的提示都表示赞赏。

console.log('Loading function');
var aws = require('aws-sdk');
var s3 = new aws.S3( apiVersion: '2006-03-01' );
exports.handler = function(event, context) 
    var bucket = event.Records[0].s3.bucket.name;
    var key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    var params = 
        Bucket: bucket,
        Key: key
    ;
    var sns = new aws.SNS();
    console.log('start of brians sns function')
    var pubResult = sns.publish(
        Message: 'Test publish to SNS from Lambda',
        TopicArn: 'arn:aws:sns:us-east-1:xxxxxxxxxxxx:lambdatop'
    , function(err, data) 
        if (err) 
            console.log(err.stack);
            return;
        
        console.log('push sent');
        console.log(data);
    );
    console.log('after sns publish:')
    console.log(pubResult)
    context.done(null, 'Brians Function Finished!');  
;

【问题讨论】:

【参考方案1】:

您在拨打publish() 之后立即拨打context.done()。 publish() 函数是一个异步调用,您无需等待它完成。另外,我不认为您的变量 pubResult 包含您期望的内容。

试试这个:

console.log('Loading function');
var aws = require('aws-sdk');
exports.handler = function(event, context) 
    var sns = new aws.SNS();
    console.log('start of brians sns function')
    sns.publish(
        Message: 'Test publish to SNS from Lambda',
        TopicArn: 'arn:aws:sns:us-east-1:xxxxxxxxxxxx:lambdatop'
    , function(err, data) 
        if (err) 
            console.log(err.stack);

            // Notify Lambda that we are finished, but with errors
            context.done(err, 'Brians Function Finished with Errors!');  
            return;
        
        console.log('push sent');
        console.log(data);

        // Notify Lambda that we are finished
        context.done(null, 'Brians Function Finished!');  
    );
;

【讨论】:

谢谢...我现在得到:errorMessage": "进程在完成请求之前退出。您知道如何等待发布完成后再退出吗? 您是否正在运行我的答案中的确切代码,并收到该错误消息?控制台日志中是否有任何错误?如果您完全复制/粘贴我的答案,并更新 TopicArn,它应该调用 SNS 发布函数,并且仅在调用发布回调后退出。 这足以让我看到我实际上遇到了安全策略错误。解决了这个问题,它就像一个冠军。谢谢! @MarkB,知道我们是否可以在上面的代码中动态获取此 TopicARN。这是我的问题,***.com/questions/44937508/…【参考方案2】:

解决此问题的另一种方法是将 SNS Publish 包装在 Promise 中,然后等待 Lambda 处理程序解决它。

exports.handler = async (event) => 
    await publishSNS(record, process.env.TOPIC_ARN);


async function publishSNS(payload, topicArn) 
    await SNS.publish(
        Message: JSON.stringify(payload),
        TargetArn: topicArn
    ).promise().then((data) => 
        console.log('SNS push succeeded: ', data);
    ).catch((err) => 
        console.error(err);
    );

【讨论】:

以上是关于AWS lambda 发送 SNS“成功”但未实际发送消息的主要内容,如果未能解决你的问题,请参考以下文章

AWS SNS - 推送 GCM 显示为从 Cloudwatch 发送但未在移动设备中接收

使用AWS Lambda从AWS SNS读取时修改JSON消息

使用 AWS Lambda 观看 SNS 主题并通过 websocket 交付?

使用 AWS Lambda 从 AWS SNS 读取时修改 JSON 消息

如何使用AWS Lambda和SNS事件触发Spring Cloud功能的重试

AWS - 在 SNS 订阅或 Lambda 函数上设置死信队列有啥区别?