首页 > 解决方案 > 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))
    }
}

在此处输入图像描述

w

标签: aws-lambda

解决方案


推荐阅读