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

## 基本資料

- 作者：劉琥（Leo Hoo）
- 開發者： Fibjs 開發者、其他貢獻者
- 程式語言：C++、JavaScript
- 作業系統：Mac OS X、Linux、Solaris、Arch Linux、FreeBSD、OpenBSD、Windows、webOS
- 類型：運行時系統
- 許可協議：GPLv3