Keep-Alive Part 1 — Using Nginx AS Backend For AWS ALB

Anderson
4 min readJun 2, 2021

--

適合讀者

  • 想理解 AWS ALB/Nginx 的 Connection 管理
  • 使用 Nginx 作為 AWS ALB Backend 的開發者

前言

AWS ELB 提供 ALB(L7) 以及 NLB (L4) 的 Load Balancer, 然而 L4/L7 Balancer 的 Keep-Alive 的實作機制是完全不一樣的, 這邊針對 AWS ALB (L7) 的 Keep-Alive Connection 管理進行詳細的說明。

HTTP Keep-Alive

當 Client 發起請求時, AWS ALB 會維護 Frond-end Connection & Back-end Connection:

[client] -> [frond-end conn| alb | back-end conn ] -> [target]

其中 Back-end Connection 會使用 使用 HTTP/1.1 Keep-Alive 發起請求到 Target, 所以 Target 必須啟用 Keep-Alive。

Back-end Connection 建立後, 因為會被 AWS ALB 重複使用, 所以不會被斷開, 然而當 Back-end Connection 進入 Idle 狀態的時候, 回收機制由兩個因素主導:

  • AWS ALB Idle Connection Timeout
  • Target Keep-Alive Timeout
  1. 如果是由 AWS ALB 檢查到 Back-end Connection Idle 的時間太長, AWS ALB 會主動向 Client & Target 發送 TCP FIN, 斷開 Frond-end Connection & Back-end Connection。
  2. 如果是由 Target 檢查到 Back-end Connection Idle 的時間太長, Target 會主動向 AWS ALB 發送 TCP FIN, 斷開與 AWS ALB 的 Back-end Connection。

我們必須確保 Target Keep-Alive Timeout 大於 AWS ALB Idle Connection Timeout, 將 Back-end Connection 的生死大權交由 AWS ALB 管理, 才不會發生 Upstream Prematurely Closed Connection 。

這邊針對幾種 Scenarios 來去做討論:

Scenario 1

[client] -> [alb] -> [node.js]
  • 確保 Node.JS 的 Keep-Alive Timeout 大於 AWS ALB Connection Idle Timeout
const server = require("http").createServer();server.keepAliveTimeout = 70000;

Scenario 2

[client] -> [alb] -> [nginx] -> [node.js]

Ingress-Nginx ConfigMap

kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-configuration
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
data:
keep-alive: "75"
upstream-keepalive-timeout: "60"

Node.JS

const server = require("http").createServer();server.keepAliveTimeout = 75000;

Summary

使用 HTTP Keep-Alive, 必須保證 Upstream Keep-Alive Timeout 大於 Downstream Idle Connection Timeout, 讓斷開 Connection 的主導權回歸 Downstream。

--

--

Anderson
Anderson

No responses yet