我在firebase上编写了一个函数,它从firebase存储中下载一个映像(base64)并将其作为响应发送给用户:
const functions = require('firebase-functions');
import os from 'os';
import path from 'path';
const storage = require('firebase-admin').storage().bucket();
export default functions.https.onRequest((req, res) => {
const name = req.query.name;
let destination = path.join(os.tmpdir(), 'image-randomNumber');
return storage.file('postPictures/' + name).download({
destination
}).then(() => {
res.set({
'Content-Type': 'image/jpeg'
});
return res.status(200).sendFile(destination);
});
});
我的客户端之后多次调用该函数(串联)以加载一系列图像以供显示,ca。 20,平均大小为4KB。
装入10张左右的照片后(数量不同),所有其他照片都会失败。原因是我的函数没有正确响应,firebase控制台告诉我我的函数引发了错误:
上图显示
给客户端的响应是默认值"错误:无法处理请求"。等待几秒钟后,所有请求都会按原样再次处理。
我最好的猜测:
是否有人知道接收错误消息的替代方法,或者遇到类似问题? (由于Firebase功能仍处于测试阶段,也可能是谷歌的错误)
顺便说一句:直接从客户端(android app,react-native)下载图像是不可能的,因为我稍后会使用该函数来检查访问权限。这个问题对我来说是可以重复的。
答案 0 :(得分:1)
在Cloud Functions中,/ tmp目录为backed by memory。因此,您在那里下载的每个文件都有效地占用了运行该函数的服务器实例上的内存。
云功能可能会重复使用服务器实例来重复调用同一个功能。这意味着您的函数正在每次调用时下载另一个文件(到同一个实例)。由于文件的名称每次都不同,因此您在/ tmp中累积每个占用内存的文件。
在某些时候,这个服务器实例将耗尽所有这些文件在/ tmp中的内存不足。这很糟糕。
这是always clean up files after you're done with them的最佳做法。更好的是,如果您可以将文件内容从云存储流式传输到客户端,那么您将使用更少的内存(and be billed even less for the memory-hours you use)。
答案 1 :(得分:0)
经过一些研究后,我找到了解决方案:Firebase控制台似乎没有显示所有错误信息。
有关您的功能的详细信息以及Firebase控制台中可能忽略的错误,请查看website from google cloud functions。
在那里我看到:内存(由@Doug Stevensson建议)使用率从未超过80MB(限制为256MB)并且从不关闭服务器。此外,我的应用程序命中了免费套餐的DNS解析限制。
documentation指向DNS resolutions: 40,000 per 100 seconds
的限制。在我的情况下,这个限制从来没有被击中 - firebase计算了环形交叉口8000的总执行次数 - 但是对于免费套餐来说似乎有一个更低,无证件限制。升级我的帐户后(我开始了GCP提供的试用,实际上没有支付任何费用)并将项目链接到结算帐户,一切都运行良好。