NGINX應用性能優化指南(第四部分):負載均衡
【編者的話】本文是“NGINX應用性能優化指南”系列文章的第四篇,主要介紹了如何從負載均衡方面實現NGINX應用性能優化。
正文
NGINX允許使用upstream
指令配置后臺。最值得注意的是會話持久化和負載均衡策略。
在會話持久化方面,有三個有用的變量需要考慮:
- 往返時間;
- 用于會話持久化的代理TCP CWND;
- 持久化會話數。
性能考量
RTT非常低則可以在代理和應用服務器之間快速建立連接,并快速提高代理的吞吐量。因此,對于(傳統的)集中配置后臺,熱連接確實可以減少處理未緩存請求的工作。
不過,如果你已經部署了反向代理,將未緩存請求引向遠程源服務器(例如海岸到海岸80毫秒),保持連接可以節省大量的連接建立時間——尤其是當你必須提供加密吞吐量的時候。(回想一下,新建一個TLS隧道需要消耗3個RTT進行協商。)
對于遠端后臺,你可能也會想用tcp_slow_start_after_idle
(在sys.net.ipv4中)。這決定了CWND的大小是否會在連接空閑(一個RTO)后恢復到初始值。通常,在正常情況下,那個行為是啟用的,而且是期望的行為。但是,如果你在使用一個專用的點對點連接,那么你會希望禁用它,因為那不太可能遇到擁塞。BDP也不大可能變化。
現在,我知道你在想什么:我沒有一個專用連接,但讓我貪心一次,無論如何都試一試!但下注時要考慮風險和回報。
在比較當前擁塞窗口大小和你對未來BDP(比如平均吞吐率乘以平均RTT)的推測時,分析真就派上用場了。還有一點值得考慮:對帶寬成本的影響,假設數據不全在遠端。
另外,如果你的BDP與初始擁塞窗口相比非常大,那么就要重新配置初始CWND。此外,對于在快速LAN(像AWS EC2)上集中部署的后臺,可能就不需要檢查其中任何一項了。
持久化后臺連接
指令keepalive
(會話持久化)設置每個工作進程同上游服務器保持的最大空閑連接數。換句話說,當一個工作進程的連接超出了keepalive
設置的數量,它會開始關閉最近最少使用的空閑連接,直到達到那個數值。可以將它想象成每個工作進程的連接池。
支持后臺keepalive
需要HTTP/1.1,因為,我們需要設置proxy_http_version
指令,并清除Connection
頭。對于NGINX:
upstream backend {
keepalive 100;
server 192.168.100.250 weight=1 max_fails=2 fail_timeout=10;
server 192.168.100.251 weight=1 max_fails=2 fail_timeout=10;
server 192.168.100.252 weight=1 max_fails=2 fail_timeout=10;
}
server {
location /http {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass http://backend;
}
}
在設置keepalive
的值時要記住以下幾點:
- 那個連接數會從代理和應用服務器的連接上限(參見
worker_connections
)中分配; - 那個值是針對每個工作進程的設置;
- 你可以已經使用
keepalive
指令配置了多個upstream
塊。
除非你已經配置了輪詢負載均衡,否則很難預測每個應用服務器上的連接分配。更準確地說,那取決于你的負載均衡策略、每個請求的處置以及請求時間。
當每個工作進程都與同一個后臺服務器建立其所有的連接時,(不大可能發生的)最壞場景就會出現。不過,那充分表明負載均衡策略需要重新考慮了。
注意:如果你在應用程序服務器上運行著一個默認NGINX配置,其worker_connections
上限會被設置為512.
負載均衡策略
NGINX提供了如下負載均衡策略:
- 加權輪詢;
ip_hash
:基于客戶端IPv4或IPv6地址的哈希;hash
:基于用戶定義鍵的哈希;least_conn
:最少活動連接數;least_time
:NGINX Plus提供了最少平均響應時間策略。
在性能方面,least_time
可能是首選,但是如果你的后臺由相同的高性能應用服務器組成,那么這種策略跟你關系就不大了。此外,hash
和ip_hash
提供了有用的選項。例如,如果應用服務器需要一段時間加載用戶資料,將同一個用戶發送給相同的后臺服務器可能會受益于緩存命中。
客戶端的IP地址由$remote_addr
變量提供。但是留心客戶端IP哈希,因為一個IP地址可能表示來自同一個NAT的多個用戶(比如公司辦公室或學校)。
來源:InfoQ