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

Node.js 是什麼

Node.js 是一個基於 Chrome v8 引擎的 Javascript 運行環境,它使用了一個"事件驅動"且"異步非阻塞 I/O" 的模型使其輕量且高效, Node.js 的包管理器 NPM 是全球最大的開源庫生態系統。前端

對其定義的補充說明:java

  • 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 入門

先給一段代碼node

var fs = require('fs')

fs.readFile('/etc/hosts', function (err, data) {
  if (err) {
     throw err;
  }
  console.log(data.toString());
});

Node.js 會建立一個讀取文件的事件,並馬上將該事件加入到事件隊列中,當前線程不會阻塞在這裏。理論上後續無論有多少線程都會進來併產生一系列事件,這些事件都會加入到一樣的事件隊列中,它們會在事件隊列中進行循環,一旦某個事件被觸發(好比讀取文件成功),就會執行後面定義的回調函數。linux

除了回調函數這種異步方式,它也提供了同步 API,代碼以下web

var fs = require('fs')

var data = fs.readFileSync('/etc/hosts')
console.log(data.toString());

Node.js 應用場景

Node.js 是針對實時 web 應用程序而開發的,很是適合爲了知足實時性較強且併發量較大的應用場景。算法

  1. I/O 密集型 web 應用shell

    應用程序分爲兩大類apache

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

    Express 是一個很是優秀的 web 框架npm

  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。

最後須要說明的是,服務網關不單單提供反向代理與服務發現特性,此外它還具有安全認證,性能監控,數據緩存,請求分片,靜態響應等特性,咱們能夠根據實際狀況擴展。

參考

  • 《架構探險—輕量級微服務架構》
相關文章
相關標籤/搜索