Fibjs是一个能在伺服器端运行JavaScript开放原始码跨平台JavaScript执行环境。Fibjs 使用 协程 , 同步风格 & 非阻塞IO模型来构建可伸缩的高可用的系统. Fibjs含有一系列内建模块,使得程序可以脱离Apache HTTP ServerIIS,作为独立的伺服器运行。Fibjs的出现降低了开发者的开发难度,并大大提升了javascript在服务端性能表现。

概览

Fibjs允许通过JavaScript和一系列模块来编写伺服器端应用和网络相关的应用。核心模块包括文件系统I/O、网络(HTTPTCPUDPDNSTLS/SSL等)、二进制数据流、加密算法、图像处理等等。[1]Fibjs模块的API形式简单,降低了编程的复杂度。

Fibjs内建了ØMQ提供了链式的消息处理器,因此可以用二十行代码[2]开发出拥有动态数据响应和静态文件服务功能的服务端框架。Fibjs的程序可以在Microsoft WindowsLinuxUnixMac OS XArch 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]

  • 2012年2月,Fibjs项目启动
  • 2012年9月,Fibjs开始在孢子社区[6]生产环境试运行
  • 2013年初,向外公开fibjs资讯
  • 2014年5月,项目推送Github[7],彻底开源
  • 2014年10月,南京源创会,首次开讲,引起业界轰动[8]
  • 2016年7月,Fibjs第4次Fiber改造,实现M:N多线程和多Fiber映射模型。[9]
  • 2017年3月,node.js南京地下铁沙龙,Fibjs作者刘琥作为特邀嘉宾介绍Fibjs,并和nodejs开发者进行了一场激烈的辩论[10]

程序示例

用Fibjs撰写的HTTP Serverhello 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将浏览器、数据(例如MongoDBRedis)等组合到一起,通过JSON提供一个统一的接口。由于前端框架和一些基本的后端开发技术(如MVCMVPMVVM等)变得流行,Fibjs也支持客户端和伺服器端重新利用相同的模型和接口。

参考文献

Wikiwand in your browser!

Seamless Wikipedia browsing. On steroids.

Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.

Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.