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