Book connected to wen
Last time I talked about how to build your own FAAS? This article will continue above to introduce some dry goods. Meanwhile, as of this writing, the core vmBox feature is open source, so please give fork a thumbs up.
Faas is a function-as-service program deployment mode proposed by cloud vendors. It takes functions as the core to achieve function-granularity service scaling. This technology is very complex, with a lot of technical information, you can check the documents of cloud vendors. Here we are talking about a relatively simple implementation, based on traditional services, using the sandbox capabilities of NodeJS to safely execute user functions and achieve the purpose of function-as-a-service.
The cause of
I believe that we will encounter multiple projects in the project to use the same function, the function has complex rules, independent logic and other characteristics of pure function, the front end is often released a NPM package, directly introduced, rough point directly copied to another project. Assuming functions such as checking the authenticity of a id number, sometimes also need to use after the end, due to differences in language, direct reuse is unlikely to put this kind of function abstract become separate function idea then arises at the historic moment, decided to try the forefront of programming ideas (front end of the world is crazy to test), thus begins the self-built faas project.
The target
Transform JS functions into API services, that is, implement functions as services
Secure execution environment VMBox
The core challenge to achieve the above goal is the safe execution environment of JS functions. The problem of node sandbox has been discussed in the last issue and will not be repeated here. The specific solution, already open source, you can click to see vmBox. Those who are interested in source code can view the code against the flow chart in the previous article. Contributions are welcome.
Getting back to the basics, VMBox is a real project-tested Node sandbox library with six features
- Forced exit in an infinite loop (if execution exceeds the specified time, there may be an infinite loop, kill child processes, release resources)
- Cross-process function calls (cross-process function calls using IPC)
- Functions call each other (using context to make calls between functions)
- Internal task queue (the child process is busy and the task script enters the queue waiting)
- Process autonomy (kill start)
- Return a promise (programmatically only as an asynchronous task)
The vmBox instance has a single run method that returns a promise and takes three arguments
Parameter names | type | If the optional | The default value | Introduction to the |
---|---|---|---|---|
code | string | mandatory | – | Js code to run |
context | object | optional | {} | Function execution context |
stack | boolean | optional | false | Other functions are called within a function, keeping track of the function call stack |
If the code runs incorrectly, an exception is thrown using promise.Reject (error) that needs to be caught
Basic usage
const VMBox = require('vmbox');
const vmBox = new VMBox({
timeout: 100.asyncTimeout: 500
});
const context = {
sum(a, b){
returna + b; }}const fn = `sum(2, 3)`
vmBox.run(fn).then(console.log)
/ / print 5
Copy the code
Advanced usage
There are a lot of things you can do with a function run context, but here is a way to call other functions from within a function.
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); / / print 30
} catch (error) {
console.log(error);
}
Copy the code
concerns
- Vmbox can solve it
vm2
In theAsynchronous dead loopHowever, the process startup cost is relatively high. Therefore, the restart of the process should be avoided as far as possible to improve the operation efficiency. - Context is the context of a function, which can inject any functionality you want to provide to the function, extend the function’s capabilities, such as database access, HTTP capabilities, and so on.
- Those of you who care about code will notice, why not use a multi-process model instead of a single-process model? There are two reasons for this. One is that the running environment of Node service is generally single-core, and single process is more practical. If multiple processes are needed, cluster module of Node can be used to encapsulate them. The second is the need to achieve mutual calls between functions, such as advanced use, multi-process calls exist in the loop.