素材网站哪个最好中国制造网站上的聊天怎么做
素材网站哪个最好,中国制造网站上的聊天怎么做,个人网站域名选择,办一家建筑公司需要哪些岗位介绍
Laf 是一个完全开源的 Serverless 框架#xff0c;Laf 的 Node.js 运行时容器 (以下简称为 Runtime) 是 Laf 的函数执行环境#xff0c;依托于 Express.js 框架。采用容器进程常驻的方式#xff0c;每一个应用对应于一个或多个容器 (弹性伸缩下)#xff0c;底层使用了…介绍
Laf 是一个完全开源的 Serverless 框架Laf 的 Node.js 运行时容器 (以下简称为 Runtime) 是 Laf 的函数执行环境依托于 Express.js 框架。采用容器进程常驻的方式每一个应用对应于一个或多个容器 (弹性伸缩下)底层使用了 Node.js 的 vm 模块使用 MongoDB 的 watch() 方法来监听函数变更事件以实现函数发布和配置发布。 Node.js vm 模块
Node.js 的 vm 模块是一个提供虚拟机功能的模块用于在 Node.js 环境中创建一个独立的 JavaScript 执行环境。它允许在应用程序中运行和控制一段 JavaScript 代码同时提供了一些安全性和隔离性。
这个模块包括一些可用于创建隔离的执行环境的函数使得代码能够在独立的上下文中运行防止对主应用程序的影响。这在某些情况下可以提供更高的安全性例如在沙盒环境中执行用户提供的代码或者实现一些动态加载和执行代码的需求。 原文链接https://forum.laf.run/d/1146 为什么要优化
目前 Laf 的函数运行时存在以下问题
频繁使用 Node.js vm 模块重复创建 vmvm 创建执行的过程中CPU 消耗很高。在以下对 runtime 的 CPU 火焰图分析可见在函数执行过程中有两部分 CPU 执行时间较长分别是输出函数请求日志和 vm 创建执行过程。 有时候遇到复杂的函数嵌套引用的时候会导致循环引用内存迟迟无法回收造成内存泄漏导致 OOM Killed。交由 runtime 自己通过 HTTP 调用的形式异步请求持久化函数日志性能损耗大QPS 直接减半。函数引擎这块的逻辑越来越复杂和臃肿维护难度很大急需重构。
如何优化
在前面的分析中我们知道当前造成性能瓶颈的原因主要有两点
为了实现隔离vm 模块重复创建CPU 消耗高特别是当函数引用达到一定规模时。另一方面复杂的引用下甚至会发生内存难以回收造成内存泄漏的问题。频繁打印函数请求日志依赖单线程的 Node.js 通过异步请求处理 console.log 等日志导致实际业务请求吞吐量下降。
因此我们采用以下优化思路
日志方面使用标准输出的形式输出日志交由 K8s 自己采集日志而不由 runtime 自己处理。 函数引擎方面第一次函数调用时构建并缓存函数模块下次调用直接取出使用不需要重复编译这块更改需要确保以下因素 保证这个缓存的函数模块是无状态即 y f(x)输入相同的 x则必然输出确定的 y。函数发布时要及时清理缓存的函数模块。
优化前后架构对比分析
优化前 优化后 优化步骤
改造日志方案为容器日志标准输出交由 K8s 收集完全去除日志的有状态依赖。重构函数引擎建立函数模块每一个函数模块的导出都是一个 JS 对象无论是代码还是引用的第三方包都被视作为一个 Module在代码中只会存在一份等同于原生的 require / export 简化代码尽可能复用保留核心逻辑去除函数模块中的有状态部分在函数执行、函数引入处建立函数模块缓存。 针对调试模式每次函数执行时重新构建函数模块主动收集执行日志。
核心函数调用逻辑
const vm require(vm)// 函数列表
const functionList {a: const b require(b); const func () b(); module.exports func,b: module.exports () hello world
}// 函数模块缓存
const functionModuleCache new Map()// 构建函数模块
const buildFunctionModule (name) {// 自定义 require 逻辑用来加载函数const customRequire (specifier) {if (functionModuleCache.has(specifier)) {return functionModuleCache.get(specifier)}if(functionList[specifier]) {return buildFunctionModule(specifier)}return require(specifier)}// 全局上下文const ctx {__require: customRequire,module: {exports: {},}}// 重新定义 requireconst wrapCode code {return const require (name) {return __require(name)}${code}module.exports;}// 构建模块const script new vm.Script(wrapCode(functionList[name]))const mod script.runInNewContext(ctx)// 缓存构建结果functionModuleCache.set(name, mod)return mod
}// 简单写一个入口函数
const main () {const func buildFunctionModule(a)const res func()console.log(res)
}main()
优化效果
压测 下面以 Laf 应用最低配置 0.1c 128m 为例进行压测。 常规 HTTP 请求 数据量测试结果QPS10 并发请求 1000 次110100 并发请求 1000 次122 WebSocket 连接 每秒创建 100 个 websocket 连接当创建 1 万个 websocket 连接时资源占用情况如下 真实案例
某个跑在 laf 上的应用日活数十万原来需要 4 个 G 的内存优化后内存降至 512 MB 以下CPU 只需要不到 1 核。
附加彩蛋
除此之外我们还做了不少额外的工作
日志支持根据不同 Level以不同的颜色输出。通过重定向自定义依赖安装路径现在支持安装和内置依赖版本不同的依赖包。拦截器现在支持类似 koa 洋葱圈结构的前拦截和后拦截的写法详情查看 Laf 文档。...
总结
通过优化 Laf 运行时我们在将每个应用的成本降低至原来的 1/10 的同时还大大提高了性能和稳定性成功把 Laf 的价格打了下来
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/88207.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!