使用 Node.js 搭建微服務網關


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 應用程序而開發的,非常適合為了滿足實時性較強且並發量較大的應用場景。

  1. I/O 密集型 web 應用

    應用程序分為兩大類

    • CPU 密集型應用
      • 對 CPU 要求較高,需要一個強大的計算過程
      • 如股票交易系統,數據分析系統等
    • I/O 密集型應用
      • 常常有頻繁的網絡傳輸或磁盤存儲現象
      • 如高並發網站,實時 Web 系統等

    Express 是一個非常優秀的 web 框架

  2. Web 聊天室 Socket.IO

  3. 命令行工具

    可以寫一段 Node.js 程序,通過 NPM 的命令將其安裝到操作系統中,隨時在命令行控制台輸入該命令運行。

    Commander.js

    基於 Node.js 的前端開發工具如下 Bower, Grunt, Gulp, Webpack, Yeoman

  4. 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 類似。

反向代理的應用場景有

  1. 使靜態資源與動態資源分離
  2. 實現 AJAX 跨域訪問
  3. 搭建統一服務網關接口

使用 Node.js 實現反向代理

Node.js 搭建反向代理服務器,需要下面 3 步

  1. 使用如下命令安裝 HTTP Proxy 模塊

    npm install http-proxy
    
  2. 使用 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)
    })
    
  3. 啟動 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。

最后需要說明的是,服務網關不僅僅提供反向代理與服務發現特性,此外它還具備安全認證,性能監控,數據緩存,請求分片,靜態響應等特性,我們可以根據實際情況擴展。

參考

  • 《架構探險—輕量級微服務架構》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM