代理一組服務器
- 使用upstream指令來定義一組服務器,指令放在http context里
-
如:
http { upstream backend { server backend1.example.com weight=5; server backend2.example.com; server 192.0.0.1 backup; } }
-
- 使用proxy_pass指令把請求打到被代理的服務器上
-
如:
server { location / { proxy_pass http://backend; } }
-
選擇一種負載均衡方法
- 默認的是權重輪詢算法,nginx會按照各個server的權重比來分發請求。
-
如:
upstream backend { server backend1.example.com; server backend2.example.com; }
-
- 最少連接法:每次都選擇連接數組少的server,如果有多個server的連接數相同,再根據這幾個server的權重分發請求。
-
例:
upstream backend { least_conn; server backend1.example.com; server backend2.example.com; }
-
- ip哈希:使用IPv4的前三個八字節位或者IPv6的全部來計算哈希值,所以相同地址的請求始終會打到相同的Server上,除非這個server不可用。
如果一個server需要暫時移除,使用down參數來避免請求打到這臺機器上,應該哈希到這臺機器上的請求會自動的發送到組里的下一臺。
-
如:
upstream backend { ip_hash; server backend1.example.com; server backend2.example.com; server backend3.example.com down; }
- 哈希:使用自定義的key去進行哈希計算。
- 通過consistent參數使用ketama一致哈希算法來減少增減服務器對客戶端的影響。
-
例:
upstream backend { hash $request_uri consistent; server backend1.example.com; server backend2.example.com; }
上面的就是通過uri進行哈希計算。
-
- 通過consistent參數使用ketama一致哈希算法來減少增減服務器對客戶端的影響。
- 最小響應時間:對于每個請求,nginx選擇平均等待時間最小并且連接數最少的。
-
通過least_time的參數來確定平均等待時間的計算方式。
- header: Time to receive the first byte from the server
- last_byte: Time to receive the full response from the server
-
如:
upstream backend { least_time header; server backend1.example.com; server backend2.example.com; }
-
服務器權重
默認的權重是1,通過weight參數來指定權重值。
通過backup來標記備用服務器,如果其他的都宕機了,請求會打到備用的服務器是上。
-
例:
upstream backend { server backend1.example.com weight=5; server backend2.example.com; server 192.0.0.1 backup; }
服務器慢啟動
對于剛剛恢復的服務器,如果一下子被請求淹沒可能會再次宕機。
可以通過server指令的slow_start參數來讓其權重從0緩慢的恢復到正常值。
-
例:
upstream backend { server backend1.example.com slow_start=30s; server backend2.example.com; server 192.0.0.1 backup; }
注意如果一個組里面只有一個server,那么max_fails,fail_timeout和slow_start參數都會被忽略。并且這個服務器永遠都不會被認為是不可用的。
Enabling Session Persistence
- Session持久性是指nginx識別客戶端的session然后把同一個session的請求路由到同一個server上。
- nginx支持三種session持久的方法,通過sticky指令去設置。
-
sticky cookie方法。通過這種方法,當server第一個響應的時候,nginx添加一個cookie來標識是哪個server響應的,當它下次請求的時候,會帶著cookie,nginx會把請求路由到同一臺server。
-
例:
upstream backend { server backend1.example.com; server backend2.example.com; sticky cookie srv_id expires=1h domain=.example.com path=/; }
-
-
sticky_route方法,使用這種方法,nginx第一個收到請求的時候會給客戶端下發一個路由。后續的請求都會帶著路由參數,nginx再來判斷請求該打到哪個server上。路由信息可以通過cookie或者uri獲取到。
-
例:
upstream backend { server backend1.example.com route=a; server backend2.example.com route=b; sticky route $route_cookie $route_uri; }
-
cookie learn 方法。通過這種方法,nginx通過檢測請求和響應來尋找session標記。通常,這些標記通過cookie傳遞。如果一個請求的包含的session標記已經learned,nginx將會把請求打到正確的server上。
-
例:
upstream backend { server backend1.example.com; server backend2.example.com; sticky learn create=$upstream_cookie_examplecookie lookup=$cookie_examplecookie zone=client_sessions:1m timeout=1h; }
在這個例子中,server通過在響應中設置一個"EXAMPLECOOKIE"來標記一個session。
create的參數指定一個變量來指示一個session的創建,在這個例子中,server發送"EXAMPLECOOKIE"表示新的session建立。
lookup的參數指定如何尋找一個已經存在的session,在這個例子中,通過查找客戶端的"EXAMPLECOOKIE"來搜索現有的session。
zone 指定一塊共享的內存來保存sticky sessions的信息。上個例子中,這塊空間叫做client_sessions,大小為1M。
-
限制連接數量
可以通過max_conns參數來限制連接數,如果達到了最大連接數,請求就可以放到通過queue指令生命的隊列中來等待后續的處理 ,queue指令設置了可以放到隊列中得最大的請求數、
-
例:
upstream backend { server backend1.example.com max_conns=3; server backend2.example.com; queue 100 timeout=70; }
如果隊列排滿或者在可選參數timeout設置的時間內無法選擇上游服務器,客戶端將接到一個錯誤。
注意如果閑置的keepalive連接在另一個worker processes中打開了max_conns限制會被忽略。導致的結果是,在多個工作進程共享內存的配置中,連接的總數可能會超過max_conns的值。
被動的健康監測
當nginx認為一個server不可用,它會暫時停止向這個server轉發請求直至nginx再次認為它是可用的。
-
nginx通過兩個參數來控制nginx的判斷
- fail_timeout,當在fail_timeout時間段內,失敗次數達到一定數量則認為該server不可用。并在接下來的fail_timeout時間內不會再將請求打到這個server上。 - max_fails,這個max_fails就是上面說的失敗的一定數量。
默認的值是10秒和1次嘗試。
-
例:
upstream backend { server backend1.example.com; server backend2.example.com max_fails=3 fail_timeout=30s; server backend3.example.com max_fails=2; }
主動的心跳檢測
使用health_check指令來檢測server是否可用,除此之外還要使用zone指令。
-
例:
http { upstream backend { zone backend 64k; server backend1.example.com; server backend2.example.com; server backend3.example.com; server backend4.example.com; } server { location / { proxy_pass http://backend; health_check; } } }
在上個例子中,nginx每五秒請求一次backend組里的每臺機器,請求地址是"/",如果失敗或者超時(或者返回的狀態碼不是2xx或者3xx),nginx就認為這個server宕機了。nginx將停止向它轉發請求,直至其再次通過心跳檢測。
可以通過參數控制health_check指令的行為。
-
例:
location / { proxy_pass http://backend; health_check interval=10 fails=3 passes=2; }
上個例子是每十秒檢測一次,如果失敗了3次就認為宕機了,如果成功2次就認為通過了檢測。
也可以檢測特定的uri
-
例:
location / { proxy_pass http://backend; health_check uri=/some/path; }
-
通過match塊自定義成功的狀態。
http { ... match server_ok { status 200-399; body !~ "maintenance mode"; } server { ... location / { proxy_pass http://backend; health_check match=server_ok; } } }
上個例子中要求status在200到399之間,并且body滿足提供的正則表達式。
-
match塊中可以包含一個status的狀態,一個body的狀態和多個header的狀態。
match welcome { status 200; header Content-Type = text/html; body ~ "Welcome to nginx!"; }
-
使用!
match not_redirect { status ! 301-303 307; header ! Refresh; }
上個例子表示status不是301、302、303或者307,并且header中不包含Refresh。
至此Nginx筆記結束,了解了這些后,對于看懂一個Nginx的配置,了解Nginx能夠實現什么功能和對其進行小改應該會有一定的幫助。