- 原文地址:Good practices for high-performance and scalable Node.js applications [Part 1/3]
- 原文作者:virgafox
- 譯文出自:掘金翻譯計劃
- 本文永久連結:github.com/xitu/gold-m…
- 譯者:jianboy
- 校對者:unicar9
在本系列的 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 連結。
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。