Node.js 是什么
Node.js 是一個基於 Chrome v8 引擎的 Javascript 運行環境,它使用了一個"事件驅動"且"異步非阻塞 I/O" 的模型使其輕量且高效, Node.js 的包管理器 NPM 是全球最大的開源庫生態系統。
對其定義的補充說明:
- Node.js 是一個運行環境,而不是 Javascript 類庫或者框架
- Node.js 是基於 Chrome 瀏覽器的 V8 引擎開發的,該引擎是業界公認的高性能 js 引擎
- Node.js 提供了事件驅動模型,可以將當前事件加入到事件隊列中輪詢
- Node.js 提供了異步非阻塞式 I/O 模型,它比傳統的同步阻塞式 I/O 模型具有更高的吞吐率
- Node.js 的包管理器與 java 的 Maven 類似,但生態圈似乎更加龐大
安裝 node.js
wget https://nodejs.org/dist/v10.15.0/node-v10.15.0-linux-x64.tar.xz
tar -xvzf node-v10.15.0-linux-x64.tar.xz -C /usr/local/ --strip-components=1
Node.js 入門
先給一段代碼
var fs = require('fs')
fs.readFile('/etc/hosts', function (err, data) {
if (err) {
throw err;
}
console.log(data.toString());
});
Node.js 會創建一個讀取文件的事件,並立刻將該事件加入到事件隊列中,當前線程不會阻塞在這里。理論上后續不管有多少線程都會進來並產生一系列事件,這些事件都會加入到同樣的事件隊列中,它們會在事件隊列中進行循環,一旦某個事件被觸發(比如讀取文件成功),就會執行后面定義的回調函數。
除了回調函數這種異步方式,它也提供了同步 API,代碼如下
var fs = require('fs')
var data = fs.readFileSync('/etc/hosts')
console.log(data.toString());
Node.js 應用場景
Node.js 是針對實時 web 應用程序而開發的,非常適合為了滿足實時性較強且並發量較大的應用場景。
-
I/O 密集型 web 應用
應用程序分為兩大類
- CPU 密集型應用
- 對 CPU 要求較高,需要一個強大的計算過程
- 如股票交易系統,數據分析系統等
- I/O 密集型應用
- 常常有頻繁的網絡傳輸或磁盤存儲現象
- 如高並發網站,實時 Web 系統等
Express 是一個非常優秀的 web 框架
- CPU 密集型應用
-
Web 聊天室 Socket.IO
-
命令行工具
可以寫一段 Node.js 程序,通過 NPM 的命令將其安裝到操作系統中,隨時在命令行控制台輸入該命令運行。
Commander.js
基於 Node.js 的前端開發工具如下 Bower, Grunt, Gulp, Webpack, Yeoman
-
HTTP 代理服務器
Node.js 可以通過異步的方式處理大量的兵法請求,它可以作為服務器端應用程序的代理,起到如 Nginx, Apache 等 HTTP代理服務器的作用。
常用的 HTTP 代理服務器模塊 node-http-proxy ,在實現微服務架構的服務網關是會用到該項技術。
npm 鏡像
淘寶提供了一個 NPM 鏡像,速度非常快。
npm install --registry=https://registry.npm.taobao.org
在安裝一個要打包到生產環境的安裝包時,你應該使用 npm install --save
,
如果你在安裝一個用於開發環境的安裝包(例如,linter, 測試庫等),你應該使用 npm install --save-dev
。可在 npm 文檔 中查找更多信息。
淘寶 npm 鏡像官網 http://npm.taobao.org/
使用 Node.js 搭建微服務網關
什么是微服務架構
先來整體回顧下下微服務架構
微服務網關(Node.js) 是微服務架構中的核心組件,它是客戶端請求的門戶,是調用具體服務端的橋梁。它類似於 Facade 模式(門面模式),將底層復雜的細節進行了屏蔽,對外提供簡單且統一的調用方式,如 HTTP 方式。
微服務網關,也稱為服務網關(Service Gateway),或者 API 網關(API Gateway)。它們之間的關系如下面架構圖所示:
在上圖中,我們使用服務網關來建立 client 與 service1 之間的聯系。當從 client 發送請求時,請求首先進入 service gateway, 隨后 service gateway 就會將請求路由到具體的服務器。在路由過程中,會涉及具體的路由算法,最簡單的做法就是在 service gateway 中解析 client 請求中的路徑和請求頭,從而路由到具體的服務端。
為了確保服務具有較高的可用性,我們可部署多個相同的服務端,此時需要再 service gateway 中設置相關路由算法,將請求隨機路由到具體的服務端,當然也可以對 client ip 地址進行 Hash 算法,從而實現請求路由。
服務網關的路由過程我們稱為"反向代理"。和 Nginx ,Apache 類似。
反向代理的應用場景有
- 使靜態資源與動態資源分離
- 實現 AJAX 跨域訪問
- 搭建統一服務網關接口
使用 Node.js 實現反向代理
Node.js 搭建反向代理服務器,需要下面 3 步
-
使用如下命令安裝 HTTP Proxy 模塊
npm install http-proxy
-
使用 HTTP Proxy 模塊啟動代理服務器,新建一個名為 app_proxy.js 的文件
var http = require('http'); var httpProxy = require('http-proxy'); var PORT = 1234; // 創建代理服務器對象 var proxy = httpProxy.createProxyServer(); proxy.on('error', function (err, req, res) { res.end(); // 輸出空白響應數據 }); var app = http.createServer(function (req, res) { // 執行反向代理 proxy.web(req, res, { target: 'http://localhost:8080' // 目標地址 }) }) app.listen(PORT, function() { console.log('server is running at %d', PORT) })
-
啟動 app_proxy.js 應用程序
node app_proxy.js
運行后,就可以通過 "localhost:1234" 去訪問 "localhost:8080"。
除了 HTTP,該模塊還支持 HTTPS 與 WebSocket 的反向代理。
可以使用 apache bench 對其性能做一個簡單的測試。模擬 1000 個用戶,每個用戶並發 100 個請求
ab -n 1000 -c 100 http://localhost:1234
Node.js 與 Nginx 相比性能不差,而且其擴展性遠高於 Nginx。我們可以動態指定被代理的目標地址,而 Nginx 中配置的目標地址卻是靜態的。這一點對實現服務發現功能及其重要,因為我們需要從 Service Registry 中獲取需要代理的微服務信息,並執行反向代理操作,調用相應的微服務 REST API。
最后需要說明的是,服務網關不僅僅提供反向代理與服務發現特性,此外它還具備安全認證,性能監控,數據緩存,請求分片,靜態響應等特性,我們可以根據實際情況擴展。
參考
- 《架構探險—輕量級微服務架構》