鍍金池/ 教程/ Java/ 負載均衡
定時任務(wù)
函數(shù)的參數(shù)
超時
一個 openresty 內(nèi)存“泄漏”問題
獲取 uri 參數(shù)
局部變量
sleep
灰度發(fā)布
TIME_WAIT
代碼覆蓋率
連接池
CentOS 平臺安裝
稀疏數(shù)組
如何只啟動一個 timer 工作?
變量的共享范圍
break,return 關(guān)鍵字
Nginx
SQL 注入
如何引用第三方 resty 庫
不同階段共享變量
獲取請求 body
動態(tài)生成的 lua-resty-redis 模塊方法
動態(tài)加載證書和 OCSP stapling
repeat 控制結(jié)構(gòu)
編碼為 array 還是 object
Nginx 靜態(tài)文件服務(wù)
執(zhí)行階段概念
Lua 函數(shù)
日期時間函數(shù)
健康監(jiān)測
與其他 location 配合
for 控制結(jié)構(gòu)
函數(shù)定義
HTTPS 時代
點號與冒號操作符的區(qū)別
String 庫
文件操作
OpenResty 最佳實踐
<code>ngx.shared.DICT</code> 非隊列性質(zhì)
使用動態(tài) DNS 來完成 HTTP 請求
代碼規(guī)范
什么是 JIT?
Windows 平臺安裝
正確的記錄日志
LuaNginxModule
不用標準庫
C10K 編程
控制結(jié)構(gòu)
請求中斷后的處理
Lua 環(huán)境搭建
Test::Nginx 能指定現(xiàn)成的 nginx.conf,而不是自動生成一個嗎
Lua 基礎(chǔ)數(shù)據(jù)類型
動態(tài)限速
PostgresNginxModule
簡單API Server框架
API 測試
location 匹配規(guī)則
虛變量
單元測試
防止 SQL 注入
select + set_keepalive 組合操作引起的數(shù)據(jù)讀寫錯誤
阻塞操作
全動態(tài)函數(shù)調(diào)用
Web 服務(wù)
典型應用場景
Nginx 新手起步
TLS session resumption
輸出響應體
調(diào)用代碼前先定義函數(shù)
module 是邪惡的
怎樣理解 cosocket
模塊
Socket 編程發(fā)展
如何對 Nginx Lua module 添加新 api
如何在后臺開啟輕量級線程完成定時任務(wù)?
如何定位問題
table 庫
json 解析的異常捕獲
如何安裝火焰圖生成工具
lua 中如何 continue
if 是邪惡的
為什么我們的域名不能被解析
抵制使用 module() 定義模塊
測試
body 在 location 中的傳遞
Lua 入門
子查詢
pipeline 壓縮請求數(shù)量
如何發(fā)起新 HTTP 請求
Lua 簡介
緩存失效風暴
Ubuntu 平臺安裝
日志輸出
緩存
Lua 面向?qū)ο缶幊?/span>
Nginx 陷阱和常見錯誤
Redis 接口的二次封裝(發(fā)布訂閱)
日志
訪問有授權(quán)驗證的 Redis
正則表達式
lock
熱裝載代碼
調(diào)用 FFI 出現(xiàn) &quot;table overflow&quot;
數(shù)據(jù)合法性檢測
禁止某些終端訪問
控制結(jié)構(gòu) if-else
調(diào)試
與 Docker 使用的網(wǎng)絡(luò)瓶頸
PostgresNginxModule 模塊的調(diào)用方式
用 do-end 整理你的代碼
FFI
什么時候使用
簡介
環(huán)境搭建
Mac OS X 平臺安裝
火焰圖
負載均衡
while 型控制結(jié)構(gòu)
如何定位 openresty 崩潰 bug
使用 Nginx 內(nèi)置綁定變量
判斷數(shù)組大小
請求返回后繼續(xù)執(zhí)行
Redis 接口的二次封裝
KeepAlive
反向代理
協(xié)議無痛升級
數(shù)學庫
元表
Vanilla 介紹
HelloWorld
LuaCjsonLibrary
持續(xù)集成
代碼靜態(tài)分析
網(wǎng)上有大量對 Lua 調(diào)優(yōu)的推薦,我們應該如何看待?
script 壓縮復雜請求
非空判斷
性能測試
函數(shù)返回值
API 的設(shè)計
kong 介紹
表達式
不支持事務(wù)
LuaRestyDNSLibrary 簡介

負載均衡

負載均衡(Load balancing)是一種計算機網(wǎng)絡(luò)技術(shù),用來在多個計算機(計算機集群)、網(wǎng)絡(luò)連接、CPU、磁盤驅(qū)動器或其他資源中分配負載,以達到最佳化資源使用、最大化吞吐率、最小化響應時間、同時避免過載的目的。

使用帶有負載均衡的多個服務(wù)器組件,取代單一的組件,可以通過冗余提高可靠性。負載均衡服務(wù)通常是由專用軟體和硬件來完成。

負載均衡最重要的一個應用是利用多臺服務(wù)器提供單一服務(wù),這種方案有時也稱之為服務(wù)器農(nóng)場。通常,負載均衡主要應用于 Web 網(wǎng)站,大型的 Internet Relay Chat 網(wǎng)絡(luò),高流量的文件下載網(wǎng)站,NNTP(Network News Transfer Protocol)服務(wù)和 DNS 服務(wù)?,F(xiàn)在負載均衡器也開始支持數(shù)據(jù)庫服務(wù),稱之為數(shù)據(jù)庫負載均衡器。

對于互聯(lián)網(wǎng)服務(wù),負載均衡器通常是一個軟體程序,這個程序偵聽一個外部端口,互聯(lián)網(wǎng)用戶可以通過這個端口來訪問服務(wù),而作為負載均衡器的軟體會將用戶的請求轉(zhuǎn)發(fā)給后臺內(nèi)網(wǎng)服務(wù)器,內(nèi)網(wǎng)服務(wù)器將請求的響應返回給負載均衡器,負載均衡器再將響應發(fā)送到用戶,這樣就向互聯(lián)網(wǎng)用戶隱藏了內(nèi)網(wǎng)結(jié)構(gòu),阻止了用戶直接訪問后臺(內(nèi)網(wǎng))服務(wù)器,使得服務(wù)器更加安全,可以阻止對核心網(wǎng)絡(luò)棧和運行在其它端口服務(wù)的攻擊。

當所有后臺服務(wù)器出現(xiàn)故障時,有些負載均衡器會提供一些特殊的功能來處理這種情況。例如轉(zhuǎn)發(fā)請求到一個備用的負載均衡器、顯示一條關(guān)于服務(wù)中斷的消息等。負載均衡器使得 IT 團隊可以顯著提高容錯能力。它可以自動提供大量的容量以處理任何應用程序流量的增加或減少。

負載均衡在互聯(lián)網(wǎng)世界中的作用如此重要,本章我們一起了解一下 Nginx 是如何幫我們完成 HTTP 協(xié)議負載均衡的。

upstream 負載均衡概要

配置示例,如下:

upstream test.net{
    ip_hash;
    server 192.168.10.13:80;
    server 192.168.10.14:80  down;
    server 192.168.10.15:8009  max_fails=3  fail_timeout=20s;
    server 192.168.10.16:8080;
}
server {
    location / {
        proxy_pass  http://test.net;
    }
}

upstream 是 Nginx 的 HTTP Upstream 模塊,這個模塊通過一個簡單的調(diào)度算法來實現(xiàn)客戶端 IP 到后端服務(wù)器的負載均衡。在上面的設(shè)定中,通過 upstream 指令指定了一個負載均衡器的名稱 test.net。這個名稱可以任意指定,在后面需要用到的地方直接調(diào)用即可。

upstream 支持的負載均衡算法

Nginx 的負載均衡模塊目前支持 6 種調(diào)度算法,下面進行分別介紹,其中后兩項屬于第三方調(diào)度算法。

  • 輪詢(默認):每個請求按時間順序逐一分配到不同的后端服務(wù)器,如果后端某臺服務(wù)器宕機,故障系統(tǒng)被自動剔除,使用戶訪問不受影響。Weight 指定輪詢權(quán)值,Weight 值越大,分配到的訪問機率越高,主要用于后端每個服務(wù)器性能不均的情況下。
  • ip_hash:每個請求按訪問 IP 的 hash 結(jié)果分配,這樣來自同一個 IP 的訪客固定訪問一個后端服務(wù)器,有效解決了動態(tài)網(wǎng)頁存在的 session 共享問題。
  • fair:這是比上面兩個更加智能的負載均衡算法。此種算法可以依據(jù)頁面大小和加載時間長短智能地進行負載均衡,也就是根據(jù)后端服務(wù)器的響應時間來分配請求,響應時間短的優(yōu)先分配。Nginx 本身是不支持 fair 的,如果需要使用這種調(diào)度算法,必須下載 Nginx 的 upstream_fair 模塊。
  • url_hash:此方法按訪問 url 的 hash 結(jié)果來分配請求,使每個 url 定向到同一個后端服務(wù)器,可以進一步提高后端緩存服務(wù)器的效率。Nginx 本身是不支持 url_hash 的,如果需要使用這種調(diào)度算法,必須安裝 Nginx 的 hash 軟件包。
  • least_conn:最少連接負載均衡算法,簡單來說就是每次選擇的后端都是當前最少連接的一個 server(這個最少連接不是共享的,是每個 worker 都有自己的一個數(shù)組進行記錄后端 server 的連接數(shù))。
  • hash:這個 hash 模塊又支持兩種模式 hash, 一種是普通的 hash, 另一種是一致性 hash(consistent)。
upstream 支持的狀態(tài)參數(shù)

在 HTTP Upstream 模塊中,可以通過 server 指令指定后端服務(wù)器的 IP 地址和端口,同時還可以設(shè)定每個后端服務(wù)器在負載均衡調(diào)度中的狀態(tài)。常用的狀態(tài)有:

  • down:表示當前的 server 暫時不參與負載均衡。
  • backup:預留的備份機器。當其他所有的非 backup 機器出現(xiàn)故障或者忙的時候,才會請求 backup 機器,因此這臺機器的壓力最輕。
  • max_fails:允許請求失敗的次數(shù),默認為 1 。當超過最大次數(shù)時,返回 proxy_next_upstream 模塊定義的錯誤。
  • fail_timeout:在經(jīng)歷了 max_fails 次失敗后,暫停服務(wù)的時間。max_fails 可以和 fail_timeout 一起使用。

當負載調(diào)度算法為 ip_hash 時,后端服務(wù)器在負載均衡調(diào)度中的狀態(tài)不能是 backup。

配置 Nginx 負載均衡

http://wiki.jikexueyuan.com/project/openresty/images/ngx_balance.png" alt="實驗拓撲" />

Nginx 配置負載均衡

upstream webservers {
    server 192.168.18.201 weight=1;
    server 192.168.18.202 weight=1;
}
server {
    listen       80;
    server_name  localhost;
    #charset koi8-r;
    #access_log  logs/host.access.log  main;
    location / {
        proxy_pass      http://webservers;
        proxy_set_header  X-Real-IP  $remote_addr;
    }
}

注,upstream 是定義在 server{ } 之外的,不能定義在 server{ } 內(nèi)部。定義好 upstream 之后,用 proxy_pass 引用一下即可。

重新加載一下配置文件

# service nginx reload
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# curl http://192.168.18.208
web1.test.com
# curl http://192.168.18.208
web2.test.com
# curl http://192.168.18.208
web1.test.com
# curl http://192.168.18.208
web2.test.com

注,大家可以不斷的刷新瀏覽的內(nèi)容,可以發(fā)現(xiàn) web1 與 web2 是交替出現(xiàn)的,達到了負載均衡的效果。

查看一下Web訪問服務(wù)器日志

Web1:

# tail /var/log/nginx/access_log
192.168.18.138 - - [04/Sep/2013:09:41:58 +0800] "GET / HTTP/1.0" 200 23 "-"
192.168.18.138 - - [04/Sep/2013:09:41:58 +0800] "GET / HTTP/1.0" 200 23 "-"
192.168.18.138 - - [04/Sep/2013:09:41:59 +0800] "GET / HTTP/1.0" 200 23 "-"
192.168.18.138 - - [04/Sep/2013:09:41:59 +0800] "GET / HTTP/1.0" 200 23 "-"
192.168.18.138 - - [04/Sep/2013:09:42:00 +0800] "GET / HTTP/1.0" 200 23 "-"
192.168.18.138 - - [04/Sep/2013:09:42:00 +0800] "GET / HTTP/1.0" 200 23 "-"
192.168.18.138 - - [04/Sep/2013:09:42:00 +0800] "GET / HTTP/1.0" 200 23 "-"
192.168.18.138 - - [04/Sep/2013:09:44:21 +0800] "GET / HTTP/1.0" 200 23 "-"
192.168.18.138 - - [04/Sep/2013:09:44:22 +0800] "GET / HTTP/1.0" 200 23 "-"
192.168.18.138 - - [04/Sep/2013:09:44:22 +0800] "GET / HTTP/1.0" 200 23 "-"

Web2:

先修改一下,Web 服務(wù)器記錄日志的格式。

# LogFormat "%{X-Real-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
# tail /var/log/nginx/access_log
192.168.18.138 - - [04/Sep/2013:09:50:28 +0800] "GET / HTTP/1.0" 200 23 "-"
192.168.18.138 - - [04/Sep/2013:09:50:28 +0800] "GET / HTTP/1.0" 200 23 "-"
192.168.18.138 - - [04/Sep/2013:09:50:28 +0800] "GET / HTTP/1.0" 200 23 "-"
192.168.18.138 - - [04/Sep/2013:09:50:28 +0800] "GET / HTTP/1.0" 200 23 "-"
192.168.18.138 - - [04/Sep/2013:09:50:28 +0800] "GET / HTTP/1.0" 200 23 "-"
192.168.18.138 - - [04/Sep/2013:09:50:28 +0800] "GET / HTTP/1.0" 200 23 "-"
192.168.18.138 - - [04/Sep/2013:09:50:28 +0800] "GET / HTTP/1.0" 200 23 "-"
192.168.18.138 - - [04/Sep/2013:09:50:28 +0800] "GET / HTTP/1.0" 200 23 "-"
192.168.18.138 - - [04/Sep/2013:09:50:29 +0800] "GET / HTTP/1.0" 200 23 "-"
192.168.18.138 - - [04/Sep/2013:09:50:29 +0800] "GET / HTTP/1.0" 200 23 "-"

注,大家可以看到,兩臺服務(wù)器日志都記錄是 192.168.18.138 訪問的日志,也說明了負載均衡配置成功。

配置 Nginx 進行健康狀態(tài)檢查

利用 max_fails、fail_timeout 參數(shù),控制異常情況,示例配置如下:

upstream webservers {
    server 192.168.18.201 weight=1 max_fails=2 fail_timeout=2;
    server 192.168.18.202 weight=1 max_fails=2 fail_timeout=2;
}

重新加載一下配置文件:

# service nginx reload
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
重新載入 nginx:                                           [確定]

先停止 Web1,進行測試:

# service nginx stop
停止 nginx:                                               [確定]
# curl http://192.168.18.208
web2.test.com
# curl http://192.168.18.208
web2.test.com
# curl http://192.168.18.208
web2.test.com

注,大家可以看到,現(xiàn)在只能訪問 Web2,再重新啟動 Web1,再次訪問一下。

# service nginx start
正在啟動 nginx:                                           [確定]
# curl http://192.168.18.208
web1.test.com
# curl http://192.168.18.208
web2.test.com
# curl http://192.168.18.208
web1.test.com
# curl http://192.168.18.208
web2.test.com

PS:大家可以看到,現(xiàn)在又可以重新訪問,說明 Nginx 的健康狀態(tài)查檢配置成功。但大家想一下,如果不幸的是所有服務(wù)器都不能提供服務(wù)了怎么辦,用戶打開頁面就會出現(xiàn)出錯頁面,那么會帶來用戶體驗的降低,所以我們能不能像配置 LVS 是配置 sorry_server 呢,答案是可以的,但這里不是配置 sorry_server 而是配置 backup。

配置 backup 服務(wù)器

備份服務(wù)器配置:

server {
    listen 8080;
    server_name localhost;
    root /data/www/errorpage;
    index index.html;
}

index.html 文件內(nèi)容:

# cat index.html
<h1>Sorry......</h1>

負載均衡配置:

upstream webservers {
    server 192.168.18.201 weight=1 max_fails=2 fail_timeout=2;
    server 192.168.18.202 weight=1 max_fails=2 fail_timeout=2;
    server 127.0.0.1:8080 backup;
}

重新加載配置文件:

# service nginx reload
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
重新載入 nginx:                                           [確定]

關(guān)閉 Web 服務(wù)器并進行測試:

# service nginx stop
停止 nginx:                                               [確定]

進行測試:

# curl http://192.168.18.208
<h1>Sorry......</h1>
# curl http://192.168.18.208
<h1>Sorry......</h1>
# curl http://192.168.18.208
<h1>Sorry......</h1>

注,大家可以看到,當所有服務(wù)器都不能工作時,就會啟動備份服務(wù)器。好了,backup 服務(wù)器就配置到這里,下面我們來配置 ip_hash 負載均衡。

配置 ip_hash 負載均衡

ip_hash:每個請求按訪問 IP 的 hash 結(jié)果分配,這樣來自同一個 IP 的訪客固定訪問一個后端服務(wù)器,有效解決了動態(tài)網(wǎng)頁存在的 session 共享問題,電子商務(wù)網(wǎng)站用的比較多。

# vim /etc/nginx/nginx.conf
upstream webservers {
    ip_hash;
    server 192.168.18.201 weight=1 max_fails=2 fail_timeout=2;
    server 192.168.18.202 weight=1 max_fails=2 fail_timeout=2;
    #server 127.0.0.1:8080 backup;
}

注,當負載調(diào)度算法為 ip_hash 時,后端服務(wù)器在負載均衡調(diào)度中的狀態(tài)不能有 backup。有人可能會問,為什么呢?大家想啊,如果負載均衡把你分配到 backup 服務(wù)器上,你能訪問到頁面嗎?不能,所以了不能配置 backup 服務(wù)器。

重新加載一下服務(wù)器:

# service nginx reload
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
重新載入 nginx:                                           [確定]

測試一下:

# curl http://192.168.18.208
web2.test.com
# curl http://192.168.18.208
web2.test.com
# curl http://192.168.18.208
web2.test.com

注,大家可以看到,你不斷的刷新頁面一直會顯示 Web2,說明 ip_hash 負載均衡配置成功。

上一篇:API 的設(shè)計下一篇:火焰圖