node.js - Azure Node.js Function App 的单例 CosmosDB 客户端
问题描述
我有一个 EventGrid 触发的 Node.js Azure 函数应用。
它可以同时接收 100 个呼叫来运行。如果进程成功或失败,它会写入 CosmosDB。
然而,CosmosDB 客户端的初始化是一个代价高昂且运行时间长的过程,因此我想在函数应用的所有 100 个实例中将这个初始化的客户端作为单例共享。
查看 Node.js 文档,它指出如果导出对象,模块将被缓存(相同实例)。https://nodejs.org/api/modules.html#modules_caching即,如果我返回一个对象,它将充当单例。
当我在 Azure 中测试我的代码时,我看到它被一遍又一遍地调用。
问题:如何在所有并发“线程”中初始化我的 CosmosDB 客户端一次。
在下面的示例代码中,我使用 5000m/s 的长时间运行操作来伪造长期运行的 Cosmos 初始化。
我昂贵的操作模块返回一个对象。
昂贵的Operation.js
const snooze = ms => new Promise(resolve => setTimeout(resolve, ms));
let value = null;
const getInstance = async (context) => {
if(value !== null) return value;
context.log("Long running process started...")
await snooze(5000);
value = 5;
return value;
}
exports.something = {
getInstance
};
index.js
const { something } = require("../expensiveOperation");
module.exports = async function (context, req) {
context.log("JavaScript HTTP trigger function processed a request.");
var first = await something.getInstance(context);
context.done();
};
解决方案
tl; dr
您做得对,但您的思维模式不正确。
长答案
我想为术语添加一些清晰度。
有函数宿主、实例和调用。文档
可以
在这里指导我们。
你的方法是正确的,但你的思维模式并不完全准确。
Azure Function 主机是黑匣子,它控制内部发生的事情以及设置新实例的时间。
根据事件网格中的消息数量,它会将您的请求映射到新实例,并且无法控制将消息映射到哪个实例。
每个实例都有自己的 CosmosDB 客户端。
推荐阅读
- resize - 如何通过门户增加 Azure 中的磁盘大小?
- django - Celery - Django - '“结果”列中的空值违反非空约束'
- javascript - 从大对象中添加和删除数组
- android - EditText 不显示
- session - 无法获取大猩猩会话。按键值
- c++ - 用户定义的转换不能在 C++ 中使用 static_cast
- javascript - 为什么在 domready 上的 document.write(x) 中没有显示字符串末尾的实体转义?
- android - NullpointerExpection returned when back pressed
- amazon-web-services - 在 beanstalk 部署期间 Nginx 配置覆盖
- events - 使用 Google Calendar V3 在资源日历中创建事件时防止冲突