我们的AWS Lambda函数获取需要从AWS Cloudfront下载到/ tmp的图像有效负载。然后它对这些图像执行一些imagemagick的简单合成。 99%的时间它完美无缺。在过去的几周内(未进行任何更改),我们现在每60分钟看到4或5504个请求超时错误。
在我们的无服务器(请参见带有跨度的屏幕截图)中,该函数调用失败,因为它超时,但是所有的Cloudfront GET均为200。到268ms,该功能所需的所有图像都已下载,并且该函数正在继续运行。但是,api最多有29秒,因此该功能似乎继续运行,尽管api网关将返回504?如果函数运行正常,我该如何克服呢?
我们启用了X射线跟踪(请参见屏幕截图),并且任何类型的函数调用错误的细节都为零?如您在屏幕快照中所见,该功能处于待处理状态。不知道从哪里去调试。收到504错误很烦人,但我真的很想知道该功能是否正常运行。
我以为Xray可以给我一些实际的痕迹,尽管我可以看到(也许我没有正确配置),但是在Xray上,此时什么都没有使函数调用超时步骤。
这是我们更简单的处理程序。我不包括其他功能,我想这可能会超时,但是它们应该非常快。映像将在短短一秒钟内生成,到S3的上传最多可能会发生几秒钟,然后发生无效,然后是无效,这可能还要再花几秒钟,如果那样呢?它不应耗时30秒,也不会引发异常。
const { getBucketObjects, buildRackImage, uploadRackImageToS3, invalidateCdn } = require('./utils')
const HTTP_OK = 200
module.exports.buildRack = async event => {
try {
let rack
try {
rack = event.rack ? event : JSON.parse(event.body)
} catch (e) {
return Promise.reject(new Error(e))
}
if (!rack.image_name) {
// eslint-disable-next-line no-throw-literal
throw 'Image name was not provided.'
}
// basic data validation that all images are either jpg or png
const errorMsg = []
if (!rack.images) {
// eslint-disable-next-line no-throw-literal
throw 'Images array is empty.'
}
for (let i = 0; i < rack.images.length; i++) {
const typeMatch = rack.images[i].image.match(/\.([^.]*)$/) // Infer the image type.
if (!typeMatch) {
errorMsg.push(`Could not determine the image type: ${rack.images[i].image}`)
}
const imageType = typeMatch[1]
if (imageType !== 'jpg' && imageType !== 'png') {
errorMsg.push(`Unsupported image type: ${rack.images[i].image}`)
}
}
if (errorMsg.length > 0) {
errorMsg.push(JSON.stringify(rack.images))
// eslint-disable-next-line no-throw-literal
throw errorMsg.join(' ')
}
/**
* Download the rack images from S3, build the rack,
* and upload to an S3 bucket
*/
const getObjectResponse = await getBucketObjects(rack)
if (!getObjectResponse) {
// eslint-disable-next-line no-throw-literal
throw getObjectResponse
}
/**
* Build the rack image locally using imagemagick
*/
const buildRackImageResponse = await buildRackImage(rack)
if (!buildRackImageResponse) {
// eslint-disable-next-line no-throw-literal
throw buildRackImageResponse
}
/**
* Upload the rack image to S3
*/
const uploadRackImageResponse = await uploadRackImageToS3(rack.image_name)
if (!uploadRackImageResponse) {
// eslint-disable-next-line no-throw-literal
throw uploadRackImageResponse
}
/**
* Invalidate the rack image name from CDN if it exists
*/
const invalidateCdnResponse = await invalidateCdn(rack.image_name)
if (!invalidateCdnResponse) {
// eslint-disable-next-line no-throw-literal
throw invalidateCdnResponse
}
return {
statusCode: HTTP_OK,
body: JSON.stringify({
message: 'Rack Successfully Built!',
statusCode: HTTP_OK,
}),
isBase64Encoded: false,
}
} catch (e) {
// eslint-disable-next-line no-console
console.log(JSON.stringify(e))
return Promise.reject(new Error(e))
}
}