天天看點

Node.js健康檢查和過載保護

作者:閃念基因
Node.js健康檢查和過載保護

[圖檔來源:unsplash.com[1]]

設想一下,你有30個Node伺服器與 "Nginx "伺服器平衡。伺服器的負載被平均配置設定,是以如果你有9000個使用者,每個伺服器有300個客戶。把負載平均配置設定給每台伺服器并不意味着你可以避免過載,因為你的工作對每個使用者都可能不同。例如,對于user_1,你可能讀取3個檔案,但對于user_2,你可能需要讀取10個(3.34倍)。根據使用者的請求過程會有更多的複雜性,這是現實中需要去思考和解決的問題。在類似于這種的情況之下,開發者不得不平衡對同每一台伺服器的請求,因為一旦這台伺服器是Server Overload(過載)的狀态,你的服務可能會挂掉。

健康檢查 每隔n秒向伺服器發送請求,以了解伺服器是否能夠處理更多的請求,如果正常,伺服器将其标記為OK,并繼續從Balancer(平衡器)接收更多的請求,否則伺服器将其标記為Error,Balancer将不會向該伺服器發送任何請求,直到Balancer再次發送健康檢查請求并标記為OK。

這個過程被稱為健康檢查。

作為檢測應用是否正常運作的機制,伺服器健康檢查通常在以下情況下使用:

  1. 高可用性
  2. 負載均衡:如果正在使用多個執行個體運作同一項目或者應用,則可以将負載平衡器配置為定期查詢每個執行個體并記錄其響應時間和狀态。
  3. 自動化部署:自動化部署過程中包括激活新版本後立即執行的測試步驟,這些測試步驟大多數都涉及到對系統元件進行基本的功能驗證或心跳監控。
  4. 監控和警報:當服務不再可通路或出現其他問題時,伺服器健康檢查可以觸發警報并通知管理者或開發人員進行幹預操作。

實際應用

以下是基于Express和Node.js實作健康檢查的簡單Demo:

  1. 安裝healthcheck子產品:使用npm或yarn等包管理工具安裝healthcheck子產品。
  2. 在Express應用中添加路由:建立一個新路由來處理/healthcheck請求,并傳回200 OK響應。
const healthCheck = require('express-healthcheck');

app.use('/health', healthCheck({
  healthy: function () {
    return { everything: 'is ok' };
  }
}));
           
  1. 向監控系統報告:如果正在使用譬如Prometheus[2]之類的監控系統,則可以将其配置為定期查詢/health接口并記錄結果。此外,還可以将結果發送到其他系統進行分析和通知。
  2. 添加自定義檢查項:除了預設提供的基本系統資訊之外,還可以編寫自己的檢查函數來測試特定元件或功能是否可用。這些函數必須傳回承諾對象并被注冊到健康檢查器中:
const checkDbConnection = async () => {
  try {
    const client = await pool.connect();
    await client.query('SELECT NOW()');
    return true;
  } catch (e) {
    console.error(e);
    return false;
  }
};

const customChecks = [checkDbConnection];

app.use('/health', healthCheck({
  healthy: function () {
    return { everything: 'is ok' };
  },
  customChecks
}));
           

結合着nginx和node.js做健康檢查

考慮到實際項目中廣泛使用Nginx的現狀,是以筆者推薦使用nginx_upstream_check_module(不随Nginx源碼分發)和Node.js來實作伺服器健康檢查:

  1. 首先,在Nginx配置檔案中啟用upstream_check子產品。例如,可以在http塊中添加如下代碼:
http {
  upstream myapp {
    server localhost:3000;

    check interval=3000 rise=2 fall=3 timeout=2000 type=http;
    check_http_send "HEAD /health HTTP/1.0\r\n\r\n";
    check_http_expect_alive http_2xx http_3xx;
  }
}
           

這将建立一個名為myapp的上遊組,并且每隔3秒鐘會向localhost:3000發送一個HTTP HEAD請求以檢查其狀态。

  1. 在Node.js應用中,按照前面提到的方法設定/ healthcheck路由(或任何其他自定義路由)。
const healthCheck = require('express-healthcheck');

app.use('/health', healthCheck({
  healthy: function () {
    return { everything: 'is ok' };
  }
}));
           
  1. 確定應用正在偵聽端口3000并運作。如果需要更改端口,請相應地更新Nginx配置檔案。
  2. 最後,在浏覽器中通路http://localhost/_nginx_health_check/myapp(根據需要更改主機和路徑),以確定Nginx正确顯示了myapp上遊元件的狀态,并且已經能夠成功連接配接到Node.js服務端點。

通過以上幾個步驟,就可以将nginx_upstream_check_module和Node.js結合起來建立一個強大的健康檢查機制。

盡管ngx_http_healthcheck_module擁有着高效、零活且易于配置的優點,但是由于其僅适用于 HTTP 服務,不支援 TCP 或 UDP 健康檢查:如果要檢測連接配接到非 Web 伺服器(如資料庫)是否正常工作,則需要另外使用第三方元件或軟體包。

HAProxy

HAProxy[3]是一個開源的負載均衡工具,可以将來自用戶端的請求分發到多個後端伺服器,并確定這些請求能夠平衡地配置設定給所有可用的伺服器。HAProxy支援多種協定,例如HTTP、TCP和SMTP等。

HAProxy最初是為高可用性而設計的,在其最簡單的形式下,它隻需配置兩個或更多台伺服器即可實作基本負載均衡。但随着時間推移和版本更新,它已經成為一款功能強大且廣泛應用于各種場景中(包括大型企業網絡)的軟體。

除了提供負載均衡之外,HAProxy還具有其他有用功能。例如:

  1. 健康檢查:HAProxy可以定期檢查後端伺服器是否健康,并根據需要啟停不健康或逾時連接配接。
  2. SSL終止:HAProxy可以在前置代理層上執行SSL加密和解密操作。
  3. 請求重寫:HAProxy允許使用ACL規則對傳入請求進行修改或過濾。
  4. 日志記錄:HAProxy生成詳細日志以便于跟蹤問題并進行性能優化。

HAProxy可以與Nginx和NodeJS結合使用,以提供一個高性能、可擴充和可靠的網絡服務基礎設施。以下是将這些技術結合起來使用的一種可能方式:

  1. 使用Nginx作為一個反向代理:在這種配置中,Nginx作為前端伺服器,接收所有來自用戶端的傳入請求,并将其轉發到适當的後端伺服器進行處理。開發者可以配置Nginx分别在80或443端口監聽HTTP或HTTPS流量。
  2. 将HAProxy配置為一個負載平衡器:HAProxy應該被配置為在運作NodeJS項目的多個後端伺服器之間配置設定傳入的流量。負載平衡算法可以根據使用者的具體需求來定制。
  3. 使用PM2部署NodeJS項目:PM2是一個程序管理器,可以輕松地在多個伺服器執行個體上管理和擴充NodeJS項目。
  4. 在負載均衡器層面上設定SSL終端:如果開發者的應用需要SSL加密,可以通過在負載平衡器上安裝SSL證書,在HAProxy層面上設定SSL終止。

下面是使用這些技術時需要考慮到的一些問題:

  • 如果應用需要在用戶端請求之間保持會話資料,可能想配置粘性會話。
  • 使用ping檢查或自定義腳本等工具監控伺服器的健康狀态。
  • 通過在Nginx和HAProxy中配置緩存規則來優化性能。

總的來說,将HAProxy與Nginx和nodeJS結合起來,為建立快速、可靠的Web服務提供了一個強大的工具集,可以處理大量的流量,同時在系統故障或中斷的情況下提供強大的故障轉移機制。

過載保護

為了檢查伺服器是否過載并防止過載,開發者通常需要檢查一些名額。這也取決于項目代碼邏輯是否完全準确無誤,但在這裡可以看到必須檢查的通用名額。

  • 事件循環延遲
  • 已用堆記憶體
  • ...

我們可以借助于overload-protection[4]這個包,可以幫助我們快速定位到這些名額。另一個值得推薦的包是event-loop-lag[5],接受一個代表重新整理事件循環滞後測量頻率的毫秒數,并傳回一個可以調用的函數,以接收最新的滞後測量值,機關為毫秒。

使用overload-protection包,我們可以指定限制,超過這個限伺服器将無法處理更多的請求。當配置的最大請求限制通過時,軟體包會自動發送503 SERVICE UNAVAILABLE。該包與http、express、restify和koa包一起工作。

但是,如果負載平衡器(Banlancer)可以發送socket進行Health Check,并且你想用socket來做,那麼就需要使用别的包來完成此事了。

結語

解釋 "健康檢查 "和 "過載保護"[6]。

"每台伺服器至少應該有一個健康檢查的實作機制,這對分布式系統來說是至關重要的。"

[1]

unsplash.com: https://unsplash.com/

[2]

Prometheus: https://prometheus.io/

[3]

HAProxy: https://www.haproxy.org/

[4]

overload-protection: https://github.com/davidmarkclements/overload-protection

[5]

event-loop-lag: https://github.com/pebble/event-loop-lag

[6]

Explaining “Health Checks” and “Overload Protection”: https://blog.bitsrc.io/nodejs-health-checks-and-overload-protection-368a132a725e

作者:MeloFor3

來源:微信公衆号:奇舞精選

出處:https://mp.weixin.qq.com/s/ig3V0iwaVea9V4VQYDm3CQ

繼續閱讀