当许多用户使用相同的功能时,Firebase 云函数截止时间错误

Firebase cloud function deadline error when many users use the same function

提问人:Carlo Casadei 提问时间:5/9/2021 更新时间:5/9/2021 访问量:78

问:

每当用户必须在存储中发布图像时,我不会直接使用 firebase 存储函数来执行此操作,而是使用 onCall 云函数,通过向其传递 base64 图像、修改它(5 次)并将其发布到存储中。

功能如下:

exports.uploadImage = functions.https.onCall(async (data, context) => {
    

   var bucket = admin.storage().bucket(); 

   // Convert the base64 string back to an image 
   var base64EncodedImageString = data.image,
   mimeType = 'image/jpeg',
   fileName = 'testName',
   imageBuffer = Buffer.from(base64EncodedImageString, 'base64');

   if (!fs.existsSync(os.tmpdir()+"/myfolder")){
      fs.mkdirSync(os.tmpdir()+"/myfolder");
  }

   const tempFilePath = path.join(os.tmpdir(),"myfolder", fileName+".jpg");


   fs.writeFileSync(tempFilePath,base64EncodedImageString,'base64',function(err){
      functions.logger.log("file scritto in"+tempFilePath);
   })
  
   await bucket.upload(tempFilePath, {
      destination: 'test/'+fileName,
      metadata: { contentType: mimeType,
         metadata: {
            firebaseStorageDownloadTokens: uuid()
         } 
       },
    });


   const tempFilePath_25 = path.join(os.tmpdir(),"myfolder", fileName+"_25.jpg");
   spawnSync('convert', [tempFilePath, '-scale', '10%','-scale','1000%>', tempFilePath_25]);
   await bucket.upload(tempFilePath_25, {
      destination: 'test/'+fileName+"_25.jpg",
      metadata: { contentType: mimeType,
         metadata: {
            firebaseStorageDownloadTokens: uuid()
         } 
       },
    });
    fs.unlinkSync(tempFilePath_25);
      
   const tempFilePath_50 = path.join(os.tmpdir(),"myfolder",  fileName+"_50.jpg");
   spawnSync('convert', [tempFilePath, '-scale', '5%','-scale','2000%>', tempFilePath_50]);
   await bucket.upload(tempFilePath_50, {
      destination: 'test/'+fileName+"_50.jpg",
      metadata: { contentType: mimeType,
         metadata: {
            firebaseStorageDownloadTokens: uuid()
         } 
       },
    });
    fs.unlinkSync(tempFilePath_50);

   const tempFilePath_75 = path.join(os.tmpdir(),"myfolder",  fileName+"_75.jpg");
   spawnSync('convert', [tempFilePath, '-scale', '3%','-scale','3333%>', tempFilePath_75]);
   await bucket.upload(tempFilePath_75, {
      destination: 'test/'+fileName+"_75.jpg",
      metadata: { contentType: mimeType,
         metadata: {
            firebaseStorageDownloadTokens: uuid()
         } 
       },
    });
    fs.unlinkSync(tempFilePath_75);

   const tempFilePath_100 = path.join(os.tmpdir(),"myfolder",  fileName+"_100.jpg");
   spawnSync('convert', [tempFilePath, '-scale', '1%','-scale','10000%>', tempFilePath_100]);
   await bucket.upload(tempFilePath_100, {
      destination: 'test/'+fileName+"_100.jpg",
      metadata: { contentType: mimeType,
         metadata: {
            firebaseStorageDownloadTokens: uuid()
         } 
       },
    });
    fs.unlinkSync(tempFilePath_100);


});

我尝试每 2 秒使用 for 循环进行模拟,结果我得到了 60% 请求的截止时间错误。当我发布应用程序时,会有很多用户(希望)可以同时调用相同的函数来发布照片。我该如何解决这个问题?提前致谢。

node.js firebase google-cloud-functions firebase-storage 截止日期

评论

0赞 Greg Fenton 5/10/2021
什么是“截止日期错误”?此外,您的代码每次都写入硬编码路径,因此您是否可能遇到同时写入同一存储桶路径的问题?您应该为文件名添加某种类型的唯一性 - 可能是时间戳或使用库,例如 .这样,并发呼叫就不会相互覆盖。uuid
0赞 Carlo Casadei 5/10/2021
错误是DEADLINE_EXCEEDED。问题是该函数需要 5 秒才能结束。如果我有很多用户,由于函数是相同的,我担心该函数具有内存限制和调用限制。
0赞 Greg Fenton 5/10/2021
您在哪里看到此错误?您是否考虑过在代码周围放置 try/catches,以确定代码的哪一部分引发了该错误?错误是在 Cloud Function 中,还是在调用 ?onCall()
0赞 Carlo Casadei 5/10/2021
错误不是来自客户端。代码是“完美的”。不要担心 uuid 和多个客户端可以相互覆盖的可能性。我知道,我会更改代码。这只是一个测试。问题是,当我用 for 循环模拟 25 个用户时,每 2 秒调用一次相同的函数,服务器会向我发送此错误。在实践中,我认为它无法管理如此多的请求。但这是一个问题,因为我的应用是一个聊天应用,所以这个函数会被很多用户调用很多次。我不能对我的用户说“服务器不可用。请稍后再试”
0赞 Carlo Casadei 5/10/2021
如果我运行该函数,我没有问题。即使我每 5 秒调用一次相同的 for 循环。没关系。问题是当我每 2 秒调用一次它时。

答: 暂无答案