搞懂分布式技術9 Nginx負載均衡原理與實踐

2021-09-20 01:41:46 字數 4766 閱讀 7862

原創: 張開濤 開濤的部落格 2017-03-24

本篇摘自《億級流量**架構核心技術》第二章 nginx負載均衡與反向** 部分內容。

當我們的應用單例項不能支撐使用者請求時,此時就需要擴容,從一台伺服器擴容到兩台、幾十台、幾百台。然而,使用者訪問時是通過如的方式訪問,在請求時,瀏覽器首先會查詢dns伺服器獲取對應的ip,然後通過此ip訪問對應的服務。

因此,一種方式是網域名稱對映多個ip,但是,存在乙個最簡單的問題,假設某台伺服器重啟或者出現故障,dns會有一定的快取時間,故障後切換時間長,而且沒有對後端服務進行心跳檢查和失敗重試的機制。

因此,外網dns應該用來實現用gslb(全域性負載均衡)進行流量排程,如將使用者分配到離他最近的伺服器上以提公升體驗。而且當某一區域的機房出現問題時(如被挖斷了光纜),可以通過dns指向其他區域的ip來使服務可用。

可以在站長之家使用「dns查詢」,查詢c.3.cn可以看到類似如下的結果。

即不同的運營商返回的公網ip是不一樣的。

對於內網dns,可以實現簡單的輪詢負載均衡。但是,還是那句話,會有一定的快取時間並且沒有失敗重試機制。因此,我們可以考慮選擇如haproxy和nginx。

而對於一般應用來說,有nginx就可以了。但nginx一般用於七層負載均衡,其吞吐量是有一定限制的。為了提公升整體吞吐量,會在dns和nginx之間引入接入層,如使用lvs(軟體負載均衡器)、f5(硬負載均衡器)可以做四層負載均衡,即首先dns解析到lvs/f5,然後lvs/f5**給nginx,再由nginx**給後端real server。

對於一般業務開發人員來說,我們只需要關心到nginx層面就夠了,lvs/f5一般由系統/運維工程師來維護。nginx目前提供了http(ngx_http_upstream_module)七層負載均衡,而1.9.0版本也開始支援tcp(ngx_stream_upstream_module)四層負載均衡。

此處再澄清幾個概念。二層負載均衡是通過改寫報文的目標mac位址為上游伺服器mac位址,源ip位址和目標ip位址是沒有變的,負載均衡伺服器和真實伺服器共享同乙個vip,如lvs dr工作模式。四層負載均衡是根據埠將報文**到上游伺服器(不同的ip位址+埠),如lvs nat模式、haproxy,七層負載均衡是根據埠號和應用層協議如http協議的主機名、url,**報文到上游伺服器(不同的ip位址+埠),如haproxy、nginx。

這裡再介紹一下lvs dr工作模式,其工作在資料鏈路層,lvs和上游伺服器共享同乙個vip,通過改寫報文的目標mac位址為上游伺服器mac位址實現負載均衡,上游伺服器直接響應報文到客戶端,不經過lvs,從而提公升效能。但因為lvs和上游伺服器必須在同乙個子網,為了解決跨子網問題而又不影響負載效能,可以選擇在lvs後邊掛haproxy,通過四到七層負載均衡器haproxy集群來解決跨網和效能問題。這兩個「半成品」的東西相互取長補短,組合起來就變成了乙個「完整」的負載均衡器。現在nginx的stream也支援tcp,所以nginx也算是乙個四到七層的負載均衡器,一般場景下可以用nginx取代haproxy。

在繼續講解之前,首先統一幾個術語。接入層、反向**伺服器、負載均衡伺服器,在本文中如無特殊說明則指的是nginx。upstream server即上游伺服器,指nginx負載均衡到的處理業務的伺服器,也可以稱之為real server,即真實處理業務的伺服器。

對於負載均衡我們要關心的幾個方面如下。

上游伺服器配置:使用upstream server配置上游伺服器。

負載均衡演算法:配置多個上游伺服器時的負載均衡機制。

失敗重試機制:配置當超時或上游伺服器不存活時,是否需要重試其他上游伺服器。

伺服器心跳檢查:上游伺服器的健康檢查/心跳檢查。

nginx提供的負載均衡可以實現上游伺服器的負載均衡、故障轉移、失敗重試、容錯、健康檢查等,當某些上游伺服器出現問題時可以將請求轉到其他上游伺服器以保障高可用,並可以通過openresty實現更智慧型的負載均衡,如將熱點與非熱點流量分離、正常流量與爬蟲流量分離等。nginx負載均衡器本身也是一台反向**伺服器,將使用者請求通過nginx**到內網中的某台上游伺服器處理,反向**伺服器可以對響應結果進行快取、壓縮等處理以提公升效能。nginx作為負載均衡器/反向**伺服器如下圖所示。

本章首先會講解nginx http負載均衡,最後會講解使用nginx實現四層負載均衡。

第一步我們需要給nginx配置上游伺服器,即負載均衡到的真實處理業務的伺服器,通過在http指令下配置upstream即可。

upstream backend else {//2.從「釋放連線池」釋放乙個連線

//3.將當前連線壓入「空閒連線池」棧頂供下次使用

ngx_queue_insert_head(&kp->conf->cache, q);

item->connection = c;

總長連線數是「空閒連線池」+「釋放連線池」的長連線總數。首先,長連線配置不會限制worker程序可以開啟的總連線數(超了的作為短連線)。另外,連線池一定要根據實際場景合理進行設定。

1.空閒連線池太小,連線不夠用,需要不斷建連線。

2.空閒連線池太大,空閒連線太多,還沒使用就超時。

另外,建議只對小報文開啟長連線。

反向**除了實現負載均衡之外,還提供如快取來減少上游伺服器的壓力。

1.全域性配置(proxy cache)

proxy_buffering on;

proxy_buffer_size 4k;

proxy_buffers 512 4k;

proxy_busy_buffers_size 64k;

proxy_temp_file_write_size 256k;

proxy_cache_lock on;

proxy_cache_lock_timeout 200ms;

proxy_temp_path /tmpfs/proxy_temp;

proxy_cache_path /tmpfs/proxy_cache levels=1:2keys_zone =cache:512m inactive=5m max_size=8g;

proxy_connect_timeout 3s;

proxy_read_timeout 5s;

proxy_send_timeout 5s;

開啟proxy buffer,快取內容將存放在tmpfs(記憶體檔案系統)以提公升效能,設定超時時間。

2.location配置

location ~ ^/backend/(.*)$ {

#設定一致性雜湊負載均衡key

#失敗重試配置

#請求上游伺服器使用get方法(不管請求是什麼方法)

proxy_method get;

#不給上游伺服器傳遞請求體

proxy_pass_request_body off;

#不給上游伺服器傳遞請求頭

proxy_pass_request_headers off;

#設定上游伺服器的哪些響應頭不傳送給客戶端

proxy_hide_header vary;

#支援keep-alive

#給上游伺服器傳遞referer、cookie和host(按需傳遞)

我們開啟了proxy_pass_request_body和proxy_pass_request_headers,禁止向上游伺服器傳遞請求頭和內容體,從而使得上游伺服器不受請求頭攻擊,也不需要解析;如果需要傳遞,則使用proxy_set_header按需傳遞即可。

我們還可以通過如下配置來開啟gzip支援,減少網路傳輸的資料報大小。

對於內容型響應建議開啟gzip壓縮,gzip_comp_level壓縮級別要根據實際壓測來決定(頻寬和吞吐量之間的抉擇)。

未完。完。 

分布式 負載均衡Nginx

step1 伺服器快取 降低資料庫壓力 step2 第一定律 就是不要使用分布式 分布式 多台伺服器完成一台伺服器做的事 每台服務完成步驟,序列完成全部 狹義分布式 廣義來說,集群也是分布式 step3 系統效能優化第一步就是快取cache 優點 1 降低伺服器壓力 2 提公升相應速度 3 成本低 ...

分布式技術

資料分布式模式 利用多台計算機並行處理多個請求,在相同的時間內完成更多的請求,解決單機效率瓶頸問題。多集群出現的問題如下 資源 乙個系統提供正常能力需要占用的硬體資源 可用性和可擴充套件性 不同分布式系統的指標 選舉流程 優點 演算法複雜度低,選舉快,簡單易實現 缺點 每個節點需要儲存全域性節點訊息...

minIO分布式集群搭建 nginx負載均衡

systemctl stop firewalld systemctl status firewalld chmod x minio 其中,minio access key 為使用者名稱,minio secret key 為密碼,密碼不能設定過於簡單,不然minio會啟動失敗,config dir 指...