1. 程式人生 > >node.js cluster多程序、負載均衡和平滑重啟

node.js cluster多程序、負載均衡和平滑重啟

1 cluster多程序

cluster經過好幾代的發展,現在已經比較好使了。利用cluster,可以自動完成子程序worker分配request的事情,就不再需要自己寫程式碼在master程序中robin式給每個worker分配任務了。

複製程式碼
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  // Fork workers.
  for (var 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(80); }
複製程式碼

上述簡單的程式碼,就實現了根據CPU個數,建立多個worker。至於實際專案中,是正好一個核對應一個worker呢,還是一個核對應2、3個worker呢,就視情況而定了。如果專案中,等待其他伺服器(例如資料庫)響應特別長時間,設定2個以上worker應該會更好。

不過一般而言,一個CPU對一個worker就挺好的了。

那麼,整個架構就類似這樣:

image

Master程序,需要做的就是監控worker的生命週期,如果發現worker掛掉了,就重啟worker,並做好相應的log。

整個架構沒有太大的難點,重點就是做好一些細節處理,例如重啟、日誌、5秒心跳包等。

多程序的架構,相對原始的單程序+pm2重啟好處肯定多很多,整個node服務會更穩定,不會突然徹底掛了。

另外,對比pm2多程序,也有優勢,主要是master的邏輯掌握在開發自己手中,可以做好自定義的log和郵件、簡訊告警。

為了整個nodejs服務管理方便,在master程序中,我們一般開啟管理埠的監聽,例如12701,通過命令列curl 127.0.0.1:12701:xxx發起一個簡單的http get請求,輕鬆管理。

例如xxx傳入reload,可以作為伺服器重啟的指令。

2 負載均衡

說到多程序,目的肯定是儘可能利用多核CPU,提高單機的負載能力。

但往往在實際專案中,受到業務邏輯的處理時間長短和系統CPU排程影響,導致實際上所有程序的負載並不是理想的徹底均衡。

官方也說了:

In practice however, distribution tends to be very unbalanced due to operating system scheduler vagaries. Loads have been observed where over 70% of all connections ended up in just two processes, out of a total of eight.

翻譯一下:70%的請求最終都落到2個worker身上,而這2個worker佔用更多的CPU資源。

那麼在實際專案部署,我們可以嘗試更進一步的措施:繫結CPU。4核CPU,我們fork出4個worker,每個worker分別繫結到#1-#4 CPU。

node並沒有給我們提供現成的介面,不過我們可以使用linux的命令:taskset

在node中,我們可以使用child_process執行shell。

複製程式碼
cp.exec('taskset -cp ' + (cpu) + ' ' + process.pid,{ 
    timeout: 5000 
},function(err,data,errData){ 
    if(err){ 
        logger.error(err.stack); 
    } 
    
    if(data.length){ 
        logger.info('\n' + data.toString('UTF-8')); 
    } 
    
    if(errData.length){ 
        logger.error('\n' + errData.toString('UTF-8')); 
    } 
});
複製程式碼

按實際情況來看,效果是不錯的。

imageimageimageimage

3 平滑重啟

每次釋出新版本,伺服器必然需要重啟。

簡單粗暴的,殺掉主程序,全部重啟,必然會有一段時間的服務中斷。

image

對於小企業還好,可以安排在凌晨重啟,但對於大公司大產品來說,就不能這麼粗暴了。

那麼我們需要平滑重啟,實現重啟過程中,服務不中斷。

策略並不複雜,但非常有效:

1、worker程序輪流重啟,間隔時間;

2、worker程序並不是直接重啟,而是先關閉新請求監聽,等當前請求都返回了,再重啟。

複製程式碼
  try {
        // make sure we close down within 30 seconds
        var killtimer = setTimeout(() => {
          process.exit(1);
        }, 30000);

        // stop taking new requests.
        server.close();

        // Let the master know we're dead.  This will trigger a
        // 'disconnect' in the cluster master, and then it will fork
        // a new worker.
        cluster.worker.disconnect();

      } catch (er2) {
      }
複製程式碼

實施了平滑重啟後,伺服器的吞吐率會平滑很多。

image

相關推薦

node.js cluster程序負載均衡平滑

1 cluster多程序 cluster經過好幾代的發展,現在已經比較好使了。利用cluster,可以自動完成子程序worker分配request的事情,就不再需要自己寫程式碼在master程序中robin式給每個worker分配任務了。 const cluster

使用Mycat實現Mysql資料庫的主從複製讀寫分離分表分庫負載均衡高可用

Mysql叢集搭建 使用Mycat實現Mysql資料庫的主從複製、讀寫分離、分表分庫、負載均衡和高可用(Haproxy+keepalived),總體架構:   說明:資料庫的訪問通過keepalived的虛擬IP訪問HAProxy負載均衡器,實現HAProxy的高可用,HAProxy用於實

Nginx + Tomcat基於HTTP協議實現反代動靜分離負載均衡session會話保持

1、演示環境: IP 作業系統 部署程式 192.168.1.143 CentOS 7.5 Nginx 192.168.1.144 CentOS 7.5 Tomcat

Apache + Tomcat基於HTTP協議實現反代動靜分離負載均衡session會話保持

1、演示環境: IP 作業系統 部署程式 192.168.1.143 CentOS 7.6 Apache 192.168.1.144 CentOS 7.6 Tomcat

Apache + Tomcat基於AJP協議實現反代動靜分離負載均衡session會話保持

1、演示環境: IP 作業系統 部署程式 192.168.1.143 CentOS 7.6 Apache 192.168.1.144 CentOS 7.6 Tomcat

nginx的配置虛擬主機負載均衡反向代理--03

第3篇主要講 URL路由重寫 和 讀寫分離 nginx中的 location 正則模組 nginx中的URL重寫怎麼做。url重寫模組,主要是在location模組面來實現,我們一點一點的看。 首先看下location 正則匹配的使用。 還記得之前是

nginx的配置虛擬主機負載均衡反向代理--02

基於域名的虛擬主機 假設我們在本地開發有3個專案,分別在hosts裡對映到本地的127.0.0.1上: 127.0.0.1 www.iyangyi.com iyangyi.com 127.0.0.1 api.iyangyi.com 127.0.0.1 a

一文弄懂Nginx中的代理與反向代理負載均衡快取

如何實現伺服器之間的協同功能呢? 通過 Nginx 提供的反向代理和負載均衡功能,可以合理的完成業

程序共享同一埠平滑升級程式的程式模型

/* File Name: server.c */ #include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> #in

zabbix 監控hbaseeshadoop程序,發出報警遠端服務。

需求:當我們的伺服器部署了很多服務後,和伺服器數量過多時,我們怎麼去管理所有的服務,以及服務程序停止,第一時間發出報警,然後先自動遠端執行服務。1、下面我們舉個例子,zabbix監控報警和自動執行服務的啟動指令。對於hadoop,hbase,es這樣的叢集部署,首先我們需要建

【Gin-API系列】守護程序平滑(八)

生產環境的API服務我們都會部署在Linux伺服器上,為了不受終端狀態的影響,啟動服務的時候會讓服務在後臺執行。那麼如何讓服務在後臺執行呢,目前有2種常見的方法。 ### 1、nohub 執行 表示忽略`SIGHUP`(結束通話)訊號,終端退出的時候所發起的結束通話訊號會被忽略。`nohup`一般會結合`&a

獨角獸公司招聘個資深技術崗位,包括網路爬蟲-後臺工程師ReactJS 前端工程師Python 後臺工程師Node.Js-後臺開發工程師PHP 後臺工程師DevOps 運維工程師 SRE

深圳樂途優聘獵頭公司獵頭顧問Mary Ma(微信lookforward1702) 歡迎使用Markdown編輯器 你好! 這是你第一次使用 Markdown編輯器 所展示的歡迎頁。如果你想學習如何使用Markdown編輯器, 可以仔細閱讀這篇文章,瞭解一下Mar

VMWare搭臺虛擬機器做叢集負載均衡主從資料庫一

最近一時興起,想搭建幾臺虛擬機器做負載均衡和資料庫主從等高階功能研究。不做安全性和其它考慮。這裡主要是為了以後測試高階的功能。 目前的想法是實現下面幾個功能: 1、負載均衡服務,能承受大量的併發訪問 2、分存式快取,以後多的東西肯定放快取裡面。 3、主從資料庫或者資料庫讀

Nginx 反向代理負載均衡與動靜分離

nginx1、環境:前端Nginx服務器:主機名:server1 IP:172.25.80.1 編譯安裝nginx1..12 後端tomcat: Server2--ip:172.25.80.2 主機名:server2 Server3--ip:172.25.80.3 主機名:server32、Ng

Linux下nginx+個Tomcat負載均衡的實現

java 負載 均衡 bootstra 火墻 瀏覽器 startup 顯示 tomcat的配置 由於項目需要,共創建了10個Tomcat端,由nginx負責轉發。9個Tomcat端口分別是8080,11000,12000,13000,14000,15000,16000,17

15套java互聯網架構師高並發集群負載均衡高可用數據庫設計緩存性能優化大型分布式 項目實戰視頻教程

二階 並發 支持 線程並發 important http 系統架構 四十 mongodb入門 * { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架構師、集群、高可用、高可擴

大型分布式項目項目實戰Springmvc+Spring+Mybatis+Maven+CMS+Redis+Solr+Linux+Nginx+單點登錄分布式緩存負載均衡視頻課程

edi mina img solr 技術 性能提升 登錄 rom nginx * { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架構師、集群、高可用、高可擴 展、高性能、高

Nginx 反向代理負載均衡

log 內存 error 通過 簡介 set ams worker 並發 ## Nginx 反向代理。 (一)簡介   一、什麽是代理服務器     客戶機原本發送給服務器的請求,不會直接發送給服務器,而是先發送給代理服務器;經過代理服務器處理後轉發給服務器;服務器數據處理

如何通俗理解——>集群負載均衡分布式

windows 高峰 介紹 一點 一個人 bsp 科學 集群 ear 轉自:周洲 (Julie)   在“高並發,海量數據,分布式,NoSql,雲計算......”概念滿天飛的年代,相信不少朋友都聽說過甚至常與人提起“集群,負載均衡”等,但不是所有人都有機會真正接觸到這些技

「mysql優化專題」高可用性負載均衡的mysql集群解決方案(12)

格式 return 建議 處理方式 sage 主機 等待 status 深度 一、為什麽需要mysql集群? 一個龐大的分布式系統的性能瓶頸中,最脆弱的就是連接。連接有兩個,一個是客戶端與後端的連接,另一個是後端與數據庫的連接。簡單如圖下兩個藍色框框(其實,這張圖是我在悟空