我正在开发一个android应用程序与firebase作为后端。还在原型阶段,单用户,没有大流量。到目前为止,我已经部署了10个云功能。到目前为止,没有调整内存(256MB)或其他设置。其中之一是从样本生成缩略图(稍微修改)。当我在测试我的应用程序时,新的图像被上传到bucket,缩略图被创建在同一个文件夹中。基本上,功能按预期工作。然而,昨天,我得到了错误前的最后一个日志语句:
Container worker exceeded memory limit of 256 MiB with 258 MiB used after servicing 29 requests total. Consider setting a larger instance class and
,然后实际错误:
Function invocation was interrupted. Error: function terminated. Recommended action: inspect logs for termination reason. Additional troubleshooting documentation can be found at https://cloud.google.com/functions/docs/troubleshooting#logging
再次说明,我目前是单个用户,到目前为止,函数可能被触发了50次左右。显然有些地方不像预期的那样工作。
这是函数:
exports.generateThumbnail = functions.storage.object().onFinalize(async (object) => {
// File and directory paths.
const filePath = object.name;
const contentType = object.contentType; // This is the image MIME type
const fileDir = path.dirname(filePath);
const fileName = path.basename(filePath);
const thumbFilePath = path.normalize(path.join(fileDir, `${THUMB_PREFIX}${fileName}`));
const tempLocalFile = path.join(os.tmpdir(), filePath);
const tempLocalDir = path.dirname(tempLocalFile);
const tempLocalThumbFile = path.join(os.tmpdir(), thumbFilePath);
//foldername in docId from pozes-test collection
const folderName = path.basename(fileDir)
const docIdFromFolderName = path.basename(fileDir)
// Exit if this is triggered on a file that is not an image.
if (!contentType.startsWith('image/')) {
return functions.logger.log('This is not an image.');
}
// Exit if the image is already a thumbnail.
if (fileName.startsWith(THUMB_PREFIX)) {
return functions.logger.log('Already a Thumbnail.');
}
// Cloud Storage files.
const bucket = admin.storage().bucket(object.bucket);
const file = bucket.file(filePath);
const thumbFile = bucket.file(thumbFilePath);
const metadata = {
contentType: contentType,
// To enable Client-side caching you can set the Cache-Control headers here. Uncomment below.
'Cache-Control': 'public,max-age=3600',
};
// Create the temp directory where the storage file will be downloaded.
await mkdirp(tempLocalDir)
// Download file from bucket.
await file.download({destination: tempLocalFile});
functions.logger.log('The file has been downloaded to', tempLocalFile);
// Generate a thumbnail using ImageMagick.
await spawn('convert', [tempLocalFile, '-thumbnail', `${THUMB_MAX_WIDTH}x${THUMB_MAX_HEIGHT}>`, tempLocalThumbFile], {capture: ['stdout', 'stderr']});
functions.logger.log('Thumbnail created at', tempLocalThumbFile);
// Uploading the Thumbnail.
await bucket.upload(tempLocalThumbFile, {destination: thumbFilePath, metadata: metadata});
functions.logger.log('Thumbnail uploaded to Storage at', thumbFilePath);
// Once the image has been uploaded delete the local files to free up disk space.
fs.unlinkSync(tempLocalFile);
fs.unlinkSync(tempLocalThumbFile);
// Get the Signed URLs for the thumbnail and original image.
const results = await Promise.all([
thumbFile.getSignedUrl({
action: 'read',
expires: '03-01-2500',
}),
file.getSignedUrl({
action: 'read',
expires: '03-01-2500',
}),
]);
functions.logger.log('Got Signed URLs.');
const thumbResult = results[0];
const originalResult = results[1];
const thumbFileUrl = thumbResult[0];
const fileUrl = originalResult[0];
// Add the URLs to the Database
if (fileName == "image_0") {
await admin.firestore().collection('testCollection').doc(docIdFromFolderName).update({thumbnail: thumbFileUrl});
return functions.logger.log('Thumbnail URLs saved to database.');
} else {
return ("fileName: " + fileName + " , nothing written to firestore")
}
这是来自我的package.json:
"dependencies": {
"firebase-admin": "^10.0.2",
"firebase-functions": "^3.22.0",
"googleapis": "^105.0.0",
"child-process-promise": "^2.2.1",
"mkdirp": "^1.0.3"
谁能解释一下发生这种情况的原因?为什么这个函数超过256MB的内存,但流量却这么少?? 这是工作记忆吗?可能是文件没有从tmp文件夹中删除?
我已经从您给定的代码和数据中重新创建了设置,但我没有像您所经历的那样得到任何类型的错误。我也尝试过一个大于20MB的大图像,但我的内存消耗仍然在60MB/call左右徘徊。
更具体地说,我也试图锤击函数提供超过40次,但仍然没有错误弹出给我。
我认为最好在你提供的generateThumbnail样本的github链接下创建一个关于这个问题的github问题,这样产品背后的实际工程师将支持你,或者你也可以尝试联系firebase支持