我们要做的是请求一个图像,例如“ media / catalog / product / 3/0/30123 / 768x / lorem.jpg”,然后我们使用位于“ media / catalog / product / 3”的原始图像/0/30123.jpg”,如果浏览器支持,则将其调整为768px和webp,然后返回新图像(如果尚未缓存)。
如果您请求:wysiwyg / lorem.jpg,它将尝试创建最大1920像素(不放大)的webp。
在小于等于1420像素的图像上,这似乎可以很好地工作。但是,在此之上,我们只会得到HTTP 502: The Lambda function returned invalid json: The json output is not parsable.
SO上也存在与GZIP相关的类似问题,但是据我了解,您不应该真正使用GZIP图像:https://webmasters.stackexchange.com/questions/8382/gzipped-images-is-it-worth/57590#57590
但是原始图像很可能已经上传到S3 GZIPPED。但是gzip可能会导致误导,因为那为什么为什么它适用于较小的图像?我们在Cloudfront中禁用了GZIP。
我为Lamda @ Edge Resize函数提供了3GB的最大资源,并具有30秒的超时时间。对于大图像来说,这还不够吗?
我已经删除了已经生成的图像,使Cloudfront无效,但其行为仍然相同。
编辑:更新:
我只是尝试了一个不同的图像,然后它就可以正常工作。。我不知道为什么以及如何解决损坏的图像……我想Cloudfront现在已经将502缓存了。 “,但没有帮助。两个原始文件均为jpg。
有效的原始源映像为6.1 MB,如果无效,则为6.7 MB。
它们具有以下限制: https://docs.aws.amazon.com/lambda/latest/dg/limits.html
response.body停止工作时约为512 MB。
答案 0 :(得分:1)
Lambda有一些较低的限制,尤其是在Lambda @ Edge的响应大小上。整个响应(包括标头和正文)的限制为1 MB。如果lambda函数返回更大的响应,它将被截断,这可能会导致HTTP 500状态。参见documentation。
您可以通过以下方法解决此问题:将结果图像保存在S3上(或者先检查是否已经存在),然后返回301重定向到与该存储桶集成的CloudFront分发,而不是返回它-因此图像请求将被重定向到结果图像。
例如在具有Origin-Response触发器的node.js中:
'use strict';
exports.handler = (event, context, callback) => {
// get response
const response = event.Records[0].cf.response;
const headers = response.headers;
// create image and save on S3, generate target_url
// ...
// modify response and headers
response.status = 301;
response.statusDescription = 'Moved Permanently';
headers['Location'] = [{key: 'Location', value: target_url}];
headers['x-reason'] = [{key: 'X-Reason', value: 'Generated.'}];
// return modified response
callback(null, response);
};
简单Lambda网关的版本(无Origin-Response,替换标头):
exports.handler = (event, context, callback) => {
// create image and save on S3, generate target_url
// ...
var response = {
status: 301,
headers: {
Location: [{
key: 'Location',
value: [],
}],
'X-Reason': [{
key: 'X-Reason',
value: '',
}],
},
};
callback(null, response);
}
答案 1 :(得分:0)
@Zbyszek答案的其他说明,您可以像这样大致估算请求是否大于1MB:
const isRequestBiggerThan1MB = (body, responseWithoutBody) => {
const responseSizeWithoutBody = JSON.stringify(responseWithoutBody).length;
return body.length + responseSizeWithoutBody >= 1000 * 1000;
};
responseWithoutBody不能太大或包含“递归键”(或所谓的“递归键”),但是在这种情况下,我无法想象您会拥有它。如果它包含递归键,则只需将其删除即可。如果responseWithoutBody太大,则需要删除这些值并分别进行测量-例如,就像我在使用response.body一样。