此代码在使用nodejs的情况下在本地运行良好。图像从s3下载,并写入文件。
但是,在Lambda中(使用nodejs 8.10),在日志中对此进行测试时,出现“内部服务器错误”消息:
“由于配置错误,执行失败:Lambda代理响应格式错误”
我在回调中使用了lambda代理响应,但是显然没有发现S3的某些AWS开发工具包错误。
我确实具有Lambda可以访问的具有S3完全访问权限的角色设置。
我的第一个Lambda函数缺少什么?我已正确遵循的文档和教程,无法正常工作。
const async = require('async')
const aws = require('aws-sdk')
const fs = require('fs')
const exec = require('child_process').exec
const bucket = 'mybucket'
const s3Src = 'bucket_prefix'
const s3Dst = 'new_prefix'
const local = `${__dirname}/local/`
aws.config.region = 'us-west-2'
const s3 = new aws.S3()
exports.handler = async (event, context, callback) => {
const outputImage = 'hello_world.png'
const rack = JSON.parse(event.body)
const images = my.images
async.waterfall([
function download(next) {
let downloaded = 0
let errors = false
let errorMessages = []
for (let i = 0; i < images.length; i++) {
let key = `${s3Src}/${images[i].prefix}/${images[i].image}`,
localImage = `${local}${images[i].image}`
getBucketObject(bucket, key, localImage).then(() => {
++downloaded
if (downloaded === images.length) { // js is non blocking, need to check if all images have been downloaded. If so, then go to next function
if (errors) {
next(errorMessages.join(' '))
} else {
next(null)
}
}
}).catch(error => {
errorMessages.push(`${error} - ${localImage}`)
++downloaded
errors = true
})
}
function getBucketObject(bucket, key, dest) {
return new Promise((resolve, reject) => {
let ws = fs.createWriteStream(dest)
ws.once('error', (err) => {
return reject(err)
})
ws.once('finish', () => {
return resolve(dest)
})
let s3Stream = s3.getObject({
Bucket: bucket,
Key: key
}).createReadStream()
s3Stream.pause() // Under load this will prevent first few bytes from being lost
s3Stream.on('error', (err) => {
return reject(err)
})
s3Stream.pipe(ws)
s3Stream.resume()
})
}
}
], err => {
if (err) {
let response = {
"statusCode": 400,
"headers": {
"my_header": "my_value"
},
"body": JSON.stringify(err),
"isBase64Encoded": false
}
callback(null, response)
} else {
let response = {
"statusCode": 200,
"headers": {
"my_header": "my_value"
},
"body": JSON.stringify(`<img src="${local}${outputImage}" />`),
"isBase64Encoded": false
}
callback(null, response)
}
}
)
}
答案 0 :(得分:1)
应始终将响应发送给回调函数。您的代码仅在错误时发送响应。这就是Lambda执行器认为您的代码失败的原因。
顺便说一句-您应该将async.waterfall中的功能用逗号分隔为两个任务吗?
答案 1 :(得分:0)
在本地,我一直在运行nodejs 10.10,而lambda当前为8.10。我敢肯定那是很大的一部分。最后,我不得不删除异步。我不得不将getBucketObject函数移出瀑布。一旦进行了这些调整,它便开始工作。另一个问题是下载的图像需要进入“ / tmp”目录。
[2018-09-25 09:47:35] [0.18ms] INSERT INTO "profiles" ("created_at","updated_at","deleted_at","email","last_login") VALUES ('2018-09-25 09:47:35','2018-09-25 09:47:35',NULL,'user@domain.com','2018-09-25 09:47:35')
[1 rows affected or returned ]