1. 程式人生 > >[譯] Node.js 高效能和可擴充套件應用程式的最佳實踐 [第 1/3 部分]

[譯] Node.js 高效能和可擴充套件應用程式的最佳實踐 [第 1/3 部分]

在本系列的 3 篇文章中,我們將介紹有關開發 Node.js Web 後端應用的一些優秀實踐。

本系列將不是關於 Node 的基礎教程,您將閱讀的所有內容都適用於已經熟悉 Node.js 基礎知識的開發者,這些內容有助於他們改進應用架構。

本文主要關注的是效率和效能,以便以更少的資源獲得最佳結果。

提高 Web 應用程式吞吐量的一種方法是對其進行擴充套件,多次例項化以處理多個傳入請求,因此本系列第一篇文章將介紹在多核或多臺機器上如何水平擴充套件 Node.js 應用程式

當您擴充套件時,您必須小心應用程式的不同方面,比如狀態和身份驗證,因此第二篇文章將介紹在擴充套件 Node.js 應用程式時必須考慮的一些注意事項

在指定的操作中,有一些推薦做法將在第三篇文章中介紹當您擴充套件到 N 個程序/機器而不打算執行 N 次時,例如拆分 api 和工作程序,採用優先順序佇列,管理週期性工作,如 cron 程序。

第 1 章 —— 水平擴充套件 Node.js 應用程式

水平擴充套件是關於複製應用程式例項來處理大量傳入請求。此操作可以在一個多核計算機上執行,也可以在不同計算機上執行。

垂直擴充套件是關於增加單機效能,並且它不涉及程式碼方面的特定操作。

同一臺機器上的多個程序

增加應用程式吞吐量的一種常用方法是為計算機的每個核生成一個程序。通過這種方式,我們就可以繼續生成和並行這種在 Node.js 中行之有效的『併發』請求管理(參見“事件驅動,非阻塞 I/O”)。

大於核心數量的程序可能並不好,因為在較低級別的程序排程,作業系統可能會均衡這些程序之間的 CPU 時間。

在一個計算機上有不同的擴充套件策略,但常見的策略是在同一埠上執行多個程序,並使用負載均衡來分配所有程序/核心上的傳入請求。

下面描述的策略是標準的 Node.js 叢集模式和自動的、更高級別的 PM2 叢集功能。

本機群集模式

本地 Node.js 叢集是在一個機器上擴充套件 Node 應用程式的基本方法(Node.js.org/api/cluster…)。您的程序的一個例項(稱為 “master”)是負責生成其他子程序(稱為 “worker”)的例項,每個程序對應一個執行應用程式的程序。 傳入請求按照所有 worker 迴圈策略進行分發,並且在同一埠上訪問。

這種方法的主要缺點是必須在程式碼內管理主程序和工作程序之間的差異,通常使用經典的 if-else 塊,而無法輕鬆修改程序中的程序數。

以下示例取自官方文件:

const cluster = require(‘cluster’);
const http = require(‘http’);
const numCPUs = require(‘os’).cpus().length;

if (cluster.isMaster) {
  
 console.log(`Master ${process.pid} is running`);
  
 // Fork workers.
 for (let i = 0; i < numCPUs; i++) {
  cluster.fork();
 }
  
 cluster.on(‘exit’, (worker, code, signal) => {
  console.log(`worker ${worker.process.pid} died`);
 });
  
} else {
  
 // Workers can share any TCP connection
 // In this case it is an HTTP server
 http.createServer((req, res) => {
  res.writeHead(200);
  res.end(‘hello world\n’);
 }).listen(8000);
  
 console.log(`Worker ${process.pid} started`);
 
}
複製程式碼

PM2 群集模式

如果您使用 PM2 作為程序管理器(我建議您使用),那麼有一個神奇的群集功能,可以讓您跨所有核心擴充套件流程,而無需擔心群集。PM2 守護程序將作為 “master”,並生成 N 個子程序作為 worker,然後利用輪詢演算法(round-robin)進行負載均衡。

通過這種方式,您可以像編寫單核用法一樣編寫應用程式(我們將在下一篇文章中介紹一些注意事項),PM2 將關注多核部分。

在群集模式下啟動應用程式後,您可以使用 “pm2 scale” 實時調整例項數,並執行 “0-second-downtime” 重新載入,其中程序將重新串聯,以便始終至少有一個線上程序。

作為程序管理器,如果 PM2 在生產中執行節點時,其他有用的程序崩潰了,PM2 也將負責重新啟動他們。

如果您需要進一步擴充套件,則可能需要部署更多計算機。

多伺服器網路負載均衡

跨多臺計算機進行擴充套件可以理解為在多個核心上進行擴充套件,有多臺計算機,每臺計算機執行一個或多個程序,以及用於將流量重定向到每臺計算機的負載均衡伺服器。

將請求傳送到特定節點後,上一段中描述的負載均衡伺服器會將流量傳送到特定程序。

可以以不同方式部署網路負載均衡伺服器。 如果您使用 AWS 來配置您的基礎架構,一個不錯的選擇是使用像 ELB(Elastic Load Balancer)這樣的託管負載均衡伺服器,因為它支援自動擴充套件等有用功能,並且易於設定。

但是簡單點,你可以自己部署一臺機器並用 NGINX 設定負載均衡。NGINX 反向代理的配置負載均衡來說非常簡單。下面是配置示例:

http {

 upstream myapp1 {
   server srv1.example.com;
   server srv2.example.com;
   server srv3.example.com;
 }
 
 server {
   listen 80;
   location / {
    proxy_pass http://myapp1;
   }
 }
 
}
複製程式碼

通過這種方式,負載均衡伺服器通過唯一埠將您的應用程式暴露給外部。如果您擔心它出現單點故障,您可以部署多個指向相同伺服器的負載均衡伺服器。

為了在負載均衡伺服器之間分配流量(每個都有自己的 IP 地址),您可以向主域新增多個 DNS“A” 記錄,因此 DNS 解析將在您配置的多個負載均衡伺服器之間分配流量,每次都解析為不同的 IP。

通過這種方式,您還可以在負載均衡伺服器上實現冗餘。

下一步

我們在這裡看到了如何在不同級別擴充套件 Node.js 應用程式,以便從您的系統架構中獲得儘可能高的效能,從單節點到多節點和多負載均衡,但要小心:如果您想使用在多程序環境中的應用程式,它必須準備好,否則您將遇到很多問題。

在下一篇文章中,我們將介紹使您的應用程式擴充套件就緒的一些注意事項。你可以在這裡找到它。


如果這篇文章對你有用,請給我點贊吧 !

如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄