aws-lambda - AWS Lambda 函数获取 504 - 端点请求间歇性超时 - 如何更好地跟踪超时原因?
问题描述
我们的 AWS Lambda 函数需要从 AWS Cloudfront 下载到 /tmp 的图像负载。然后它在这些图像上执行一些简单的图像合成。99% 的时间它都能完美运行。在过去的几周中(未进行任何更改),我们现在每 60 分钟看到 4 或 5 504 个请求超时错误。
在我们的无服务器(参见带有 spans 的屏幕截图)中,函数调用失败,因为它超时了,但是所有的云端 GET 都是 200。到 268 毫秒时,函数需要的所有图像都已下载,并且函数似乎正在运行。但是,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))
}
}
解决方案
推荐阅读
- nativescript - 在 Android 上运行 nativescript 应用程序时出错
- laravel - 如何在 laravel 5.7 中获取当前视图名称(页面名称)
- java - 有没有办法在netty中获取端口信息?
- excel - 将 sumifs 函数添加到 VBA
- xcode - Xcode 10 不使用 ssh 推送
- javascript - 在使用 Nuxt 的 SSR 期间未调用 Vue 实例`watcher`
- css - React-bootstrap:反转复选框输入,因此标签文本首先出现
- android - Dagger 2 如何将对象注入测试
- android - 无法通过 rn4020 从 android 应用程序获取全文消息
- javascript - 使用参数执行回调函数的优雅方式