適合讀者
- 理解 TCP Keep-Alive & HTTP Keep-Alive
- 想理解 AWS NLB/Nginx 的 Connection 管理
- 使用 Nginx 作為 AWS NLB Backend 的開發者
前言
AWS ELB 提供 NLB (L4) 的 Load Balancer, L4 Load Balancer 使用 TCP Keep-Alive 機制, TCP Keep-Alive 跟 HTTP Keep-Alive 是兩碼子事, 簡單而言, TCP Keep-Alive 的機制是透過長時間連線, 藉由定時 Ping/Pong 的機制來管理 Connection。
AWS NLB 的 Connection Idle Time 為 350 秒, Connection 超時之後, AWS NLB 不主動斷開連線, 而是當 Client/Target 撿起超時的 Connection 傳送封包後, AWS NLB 才會回傳 TCP RST 告知 Client/Target 這條連線已經超時, 藉由這樣的機制, 我們必須把 Client/Target 的 Keep-Alive Timeout 設為 比 AWS NLB 350 秒短, 才不會讓 Client/Target 撿到過期的 Connection。
Scenario 1
[client] -> [nlb] -> [node.js]
- 確保 Node.JS 的 Keep-Alive Timeout 小於 AWS NLB Connection Idle Timeout
const server = require("http").createServer();server.keepAliveTimeout = 70000;
Scenario 2
[client] -> [nlb|l4] -> [nginx|l7] -> [node.js]
nlb 為 nginx 提供 L4 的均衡負載, nginx 為 node.js 提供 L7 的均衡負載, 所以這邊必須這樣設定:
- 確保 Nginx Keep-Alive Timeout 小於 AWS NLB Idle Connection Timeout
- 確保 Node.JS Keep-Alive Timeout 大於 Nginx Upstream Keep-Alive Timeout
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
TPC Keep-Alive 與 HTTP Keep-Alive 是截然不同的機制, 使用 L4 LoadBalancer, 必須保證 Upstream Keep-Alive Timeout 小於 Load Balancer Idle Connection Timeout, 避免 Target 撿到過期的 Connection。