上次谈到了如何搭建本身的faas?,被同行评论有些标题党,这篇文章将接着上文,来介绍一些干货。同时在写这篇文章的时候,核心功能vmbox已经开源,欢迎你们点赞fork。javascript
faas
是云厂商提出的一种函数即服务
的程序部署模式,以函数为核心,实现以函数粒度的服务伸缩,这项技术很是复杂,有不少的技术资料,你们能够查看云厂商的文档。咱们这里聊到的是比较简单的实现方式,以传统服务为基础,借用nodejs的沙盒能力,实现安全执行用户的函数,达到函数即服务的目的。前端
相信你们项目中都会遇到多个项目使用同一个函数
,该函数具备规则复杂
、逻辑独立
等特色的纯函数,前端每每是发布一个npm包,直接引入,粗暴点的直接复制到另外一个项目中。假设校验身份证件号的真伪等函数,有时后端也须要用,因为语言的差别,直接复用不太可能,将这类函数抽象成为单独的函数的想法便应运而生,决定尝试最前沿的编程思想(前端的世界就是疯狂试探),自建faas工程就这样开始了。java
将js函数转化为API服务,即实现函数即服务
node
实现上述目标的核心难题是js函数的安全执行环境,上一期已经谈到node的沙盒存在的问题,这里再也不赘述。具体的解决方案,已经开源,你们能够点击查看vmbox。对源码感兴趣的同窗能够对照上篇文章中的流程图查看代码,欢迎贡献。git
回归正题,vmbox
是通过真实项目检验的node沙盒库,具备六大特色github
vmbox的实例只有一个run
方法,返回值是一个promise
,接收三个参数数据库
参数名 | 类型 | 是否选填 | 默认值 | 简介 |
---|---|---|---|---|
code | string | 必填 | - | 运行的js代码 |
context | object | 选填 | {} | 函数运行上下文 |
stack | boolean | 选填 | false | 函数内调用其余函数,记录函数调用栈 |
若是代码运行出错,会使用Promise.reject(error)抛出异常,须要对异常进行捕获npm
基本用法编程
const VMBox = require('vmbox');
const vmBox = new VMBox({
timeout: 100,
asyncTimeout: 500
});
const context = {
sum(a, b){
return a + b;
}
}
const fn = `sum(2, 3)`
vmBox.run(fn).then(console.log)
// 打印5
复制代码
高级用法后端
借助函数运行上下文,能够作不少事情,下面实现了一个从函数内部调用其余函数的方法。
const VMBox = require('vmbox');
const vmBox = new VMBox({
timeout: 100,
asyncTimeout: 500
});
const fnGroup = {
sum: `async function main({params, fn}){ const {a, b} = params; return a + b }`,
caller: `async function main({params, fn}){ return await fn.call('sum', params); }`
};
async function run(code, context, stack = false) {
const runCode = code + `;\n(async () => { return await main({params, fn}); })()`
return vmBox.run(runCode, context, stack);
}
const fn = {
call: (name, params) => {
const code = fnGroup[name];
if (code) {
return run(code, { params, fn }, true);
} else {
return null;
}
}
}
const context = {
fn,
params: {
a: 10,
b: 20
}
}
const code = fnGroup.caller;
try {
const res = await run(code, context);
console.log(res); // 打印30
} catch (error) {
console.log(error);
}
复制代码
vm2
中异步死循环的问题,可是进程启动的成本比较高,所以在使用过程当中尽可能避免进程的重启,提升运行效率。