Fibjs

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

## 概览
Fibjs允许通过JavaScript和一系列模块来编写服务器端应用和网络相关的应用。核心模块包括文件系统I/O、网络（HTTP、TCP、UDP、DNS、TLS/SSL等）、二进制数据流、加密算法、图像处理等等。Fibjs模块的API形式简单，降低了编程的复杂度。

Fibjs内置了ØMQ提供了链式的消息处理器,因此可以用二十行代码开发出拥有动态数据响应和静态文件服务功能的服务端框架。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的作者、中国著名社区网站西祠胡同创始人。

Fibjs的出现源自于一个名为“孢子社区”的一个项目，在做技术选型的时候考虑到前后端代码复用，方便招聘开发人员等原因，决定将后端转向JS平台。当时，刘琥认为Node.js的异步开发模式不是一个适合大规模部署的方式，会给开发和维护带来很大问题。刘琥更倾向于使用Go的方式来实现异步，从而能达到更高的并发，于是Fibjs就出现了。

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

## 程序示例
用Fibjs撰写的HTTP Server版hello world示例：


```javascript
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)之前输入的信息：


```javascript
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也支持客户端和服务器端重新利用相同的模型和接口。

## 参考文献