Fibjs
Fibjs是一个能在服务器端运行JavaScript的开放源代码、跨平台JavaScript执行环境。Fibjs 使用 协程 , 同步风格 & 非阻塞IO模型来构建可伸缩的高可用的系统. Fibjs含有一系列内置模块,使得程序可以脱离Apache HTTP Server或IIS,作为独立的服务器运行。Fibjs的出现降低了开发者的开发难度,并大大提升了javascript在服务端性能表现。
原作者 | 刘琥(Leo Hoo) |
---|---|
开发者 | Fibjs 开发者、其他贡献者 |
源代码库 | Fibjs Repository |
编程语言 | C++、JavaScript |
操作系统 | Mac OS X、Linux、Solaris、Arch Linux、 FreeBSD、OpenBSD、Windows、webOS |
类型 | 运行时系统 |
许可协议 | GPLv3 |
网站 | fibjs |
概览
Fibjs允许通过JavaScript和一系列模块来编写服务器端应用和网络相关的应用。核心模块包括文件系统I/O、网络(HTTP、TCP、UDP、DNS、TLS/SSL等)、二进制数据流、加密算法、图像处理等等。[1]Fibjs模块的API形式简单,降低了编程的复杂度。
Fibjs内置了ØMQ提供了链式的消息处理器,因此可以用二十行代码[2]开发出拥有动态数据响应和静态文件服务功能的服务端框架。Fibjs的程序可以在Microsoft Windows、Linux、Unix、Mac OS X、Arch Linux等服务器上运行。Fibjs也可以使用CoffeeScript(一种旨在简化JavaScript的替代语言,其代码可按照一定规则转化为合法的JavaScript代码)、TypeScript(微软开发的强化了数据类型的JavaScript变体)、Dart语言,以及其他能够编译成JavaScript的语言编程。
Fibjs主要用于编写像Web服务器一样的网络应用,这和Node.js是类似的。但是Fibjs与Node.js最大的不同在于,Node.js是非阻塞的(多条命令可以同时被运行,通过回调函数得知命令已结束运行),而Fibjs是阻塞的,它的风格更接近C语言,它的机制和Go更像,Fibjs采用了非阻塞IO模型,但是提供给用户使用的API是阻塞的,它的特色是使用coroutine中文名字叫协程这和Go所采用的Goroutine十分相像,使得阻塞API不会阻塞javascript线程,从而达到更大的并发。因此Fibjs也非常地适合网络服务。
Coroutine是类似线程的概念(但Coroutine并不是线程)。线程属于系统层面,通常来说创建一个新的线程会消耗较多的资源且管理不易。而 Coroutine就像轻量级的线程,但我们称其为并发,一个Fibjs程序可以运行超过数万个 Coroutine,并且这些性能都是原生级的,随时都能够关闭、结束。一个核心里面可以有多个Coroutine。 在内置的官方包中也不时能够看见Coroutine的应用,像是net/http中用来监听网络服务的函数实际上是创建一个不断运行循环的Coroutine。
Fibjs使用Google V8 JavaScript 引擎,因为:
- V8的线程支持Coroutine重入
- V8是基于BSD许可证的开源软件
- V8速度非常快
- V8专注于网络功能,在HTTP、DNS、TCP等方面更加成熟
Fibjs内置近150个内置模块和对象, 已经有数十万个javascript模块,它们可以通过一个名为npm的管理器免费下载。
历史
Fibjs于2012年写成,其作者是刘琥(Leo Hoo),网名叫作响马,圈内人都尊称他大叔或马叔。刘琥同时是开源服务器应用框架Netbox[3][4]的作者、中国著名社区网站西祠胡同创始人。
Fibjs的出现源自于一个名为“孢子社区”的一个项目,在做技术选型的时候考虑到前后端代码复用,方便招聘开发人员等原因,决定将后端转向JS平台。当时,刘琥认为Node.js的异步开发模式不是一个适合大规模部署的方式,会给开发和维护带来很大问题。刘琥更倾向于使用Go的方式来实现异步,从而能达到更高的并发,于是Fibjs就出现了。[5]
程序示例
用Fibjs撰写的HTTP Server版hello world示例:
const http = require('http');
let svr = new http.Server("", 8000, (request) => {
request.response.setHeader('Content-Type','text/plain');
request.response.write('Hello World!');
});
console.log('Server running at http://127.0.0.1:8000/');
svr.start();
另一个简单的TCP服务器示例,监听(Listening)端口7000并输出 (echo)之前输入的信息:
const net = require('net');
const coroutine = require('coroutine');
let s = new net.Socket();
s.bind(8000);
s.listen();
coroutine.start(() => {
while(1) {
coroutine.start((c)=>{
console.log(c.remoteAddress, c.remotePort, "->",c.localAddress, c.localPort);
try {
var b;
while (b = c.recv())
c.send(b);
} finally {
c.close();
c.dispose();
}
}, s.accept());
}
});
console.log("Tcp Server listen on port 8000");
上例中第二个程序,演示了如何使用Coroutine,coroutine使得while(1)不会阻塞后面的代码从而实现了并发。
技术
Coroutine
Fibjs以单线程运行,使用非阻塞I/O调用,这样既可以支持数以万计的并发连接,又不会因多线程本身的特点而带来麻烦。众多请求只使用单线程的设计意味着可以用于建立高并发应用程序。Fibjs应用程序的设计目标是任何需要操作I/O的函数都使用Coroutine协程来完成。当使用Fibjs进行服务器应用开发时,每次和客户端建立连接都会创建一个Fiber(task)放在队列中等待,javascript线程依次取fiber执行,每当执行到I/O操作,Coroutine都会把上下文切换到后台线程(worker thread)来完成相应的操作,并且把Javascript的上下文被切换到下一个fiber中继续执行。当后台线程的fiber执行完毕之后会重新把fiber丢进队列尾部等待,等待Javascript执行到该fiber。从而完成这个异步操作。
V8
V8是为Google Chrome设计的JavaScript运行引擎,Google于2008年将其开源。V8用C++写成,它将JavaScript源代码编译成本地机器码而不是随时解释。
Fibjs的核心功能被包含进一个JavaScript库,并通过C++将各部分与操作系统进行联系。
npm
npm是Node.js附带的包管理器。Fibjs高度兼容了npm。npm是一个命令行工具,用于从NPM Registry中下载、安装Fibjs程序,同时解决依赖问题。npm提高了开发的速度,因为它能够负责第三方Fibjs程序的安装与管理。
统一API
Fibjs将浏览器、数据(例如MongoDB或Redis)等组合到一起,通过JSON提供一个统一的接口。由于前端框架和一些基本的后端开发技术(如MVC、MVP、MVVM等)变得流行,Fibjs也支持客户端和服务器端重新利用相同的模型和接口。
参考文献
- ^ Modules (页面存档备份,存于互联网档案馆), fibjs Website
- ^ Fibjs Httpserver Examples. [2017-09-07]. (原始内容存档于2017-09-07).
- ^ NetBox official website. [2017-09-07]. (原始内容存档于2017-09-04).
- ^ Netbox source code. [2017-09-07]. (原始内容存档于2018-06-11).
- ^ 认识Fibjs. [2017-09-07]. (原始内容存档于2019-02-16).
- ^ Fibjs community. [2017-09-07]. (原始内容存档于2017-09-07).
- ^ project github. [2017-09-04]. (原始内容存档于2018-06-11).
- ^ fibjs机制ppt. [2017-09-07]. (原始内容存档于2017-09-07).
- ^ Fibjs线程和Fiber模型 (PDF). [2017-09-07]. (原始内容存档 (PDF)于2017-09-07).
- ^ Fibjs vs Node.js