第一章 反向代理
Nginx代理服務(wù)基本概述
1.代理一詞往往并不陌生, 該服務(wù)我們常常用到如(代理理財(cái)、代理租房、代理收貨等等),如下圖所示

2.在沒有代理模式的情況下,客戶端和 Nginx 服務(wù)端,都是客戶端直接請(qǐng)求服務(wù)端,服務(wù)端直接響應(yīng)客戶端。

3.那么在互聯(lián)網(wǎng)請(qǐng)求里面, 客戶端往往無法直接向服務(wù)端發(fā)起請(qǐng)求, 那么就需要用到代理服務(wù), 來實(shí)現(xiàn)客戶端和服務(wù)通信,如下圖所示

正向代理和反向代理
以訪問Goo為例,客戶端連接到VPN相當(dāng)于正向代理
VPN代理請(qǐng)求訪問后端服務(wù)器并返回屬于反向代理
Nginx代理服務(wù)支持的協(xié)議
1.Nginx 作為代理服務(wù),可支持的代理協(xié)議非常的多,具體如下圖

2.如果將 Nginx 作為反向代理服務(wù),常常會(huì)用到如下幾種代理協(xié)議,如下圖所示

3.反向代理模式與 Nginx 代理模塊總結(jié)如表格所示

Nginx反向代理配置語法
1.Nginx代理配置語法
Syntax: proxy_pass URL;
Default: —
Context: location, if in location, limit_except
http://localhost:8000/uri/
http://192.168.56.11:8000/uri/
http://unix:/tmp/backend.socket:/uri/
2.添加傳遞給后端服務(wù)器的請(qǐng)求頭信息
Syntax: proxy_set_header field value;
Default: proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
Context: http, server, location
# 用戶請(qǐng)求的時(shí)候 HOST 的值是 www.oldboy.com, 那么代理服務(wù)會(huì)像后端傳遞請(qǐng)求的還是 www.oldboy.com
proxy_set_header Host $http_host;
# 將$remote_addr 的值放進(jìn)變量 X-Real-IP 中, $remote_addr 的值為客戶端的 ip
proxy_set_header X-Real-IP $remote_addr;
# 客戶端通過代理服務(wù)訪問后端服務(wù), 后端服務(wù)通過該變量會(huì)記錄真實(shí)客戶端地址
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
3.代理到后端的TCP連接數(shù),響應(yīng),返回等超時(shí)時(shí)間
//nginx 代理與后端服務(wù)器連接超時(shí)時(shí)間(代理連接超時(shí))
Syntax: proxy_connect_timeout time;
Default: proxy_connect_timeout 60s;
Context: http, server, location
//nginx 代理等待后端服務(wù)器的響應(yīng)時(shí)間
Syntax: proxy_read_timeout time;
Default: proxy_read_timeout 60s;
Context: http, server, location
//后端服務(wù)器數(shù)據(jù)回傳給 nginx 代理超時(shí)時(shí)間
Syntax: proxy_send_timeout time;
Default: proxy_send_timeout 60s;
Context: http, server, location
4.代理緩沖區(qū)
//nignx 會(huì)把后端返回的內(nèi)容先放到緩沖區(qū)當(dāng)中,然后再返回給客戶端,邊收邊傳, 不是全部接收完再傳給客戶端
Syntax: proxy_buffering on | off;
Default: proxy_buffering on;
Context: http, server, location
//設(shè)置 nginx 代理保存用戶頭信息的緩沖區(qū)大小
Syntax: proxy_buffer_size size;
Default: proxy_buffer_size 4k|8k;
Context: http, server, location
//proxy_buffers 緩沖區(qū)
Syntax: proxy_buffers number size;
Default: proxy_buffers 8 4k|8k;
Context: http, server, location
5.proxy代理網(wǎng)站常用配置
將配置寫入新文件,調(diào)用時(shí)使用include引用即可
[root@lb01 ~]# cat /etc/nginx/proxy_params
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
6.代理配置location時(shí)調(diào)用,方便后面多個(gè)location重復(fù)使用
location / {
proxy_pass http://127.0.0.1:8080;
include proxy_params;
}
Nginx反向代理實(shí)戰(zhàn)
配置關(guān)系圖:

1.環(huán)境準(zhǔn)備
lb01 代理服務(wù)器
web01 web服務(wù)器
2.web01服務(wù)器配置
配置一個(gè)網(wǎng)站,監(jiān)聽在 8080,此時(shí)網(wǎng)站僅 172 網(wǎng)段的用戶能訪問
[root@web01 ~]# cd /etc/nginx/conf.d/
[root@web01 conf.d]# vim web.conf
server {
listen 8080;
server_name localhost;
location / {
root /code;
index index.html;
deny 10.0.0.0/24;
allow all;
}
}
[root@web01 conf.d]# mkdir /code
[root@web01 conf.d]# echo "web01-7" >/code/index.html
[root@web01 conf.d]# systemctl restart nginx
3.配置lb01代理服務(wù)器
配置監(jiān)聽 eth0 的 80 端口,使 10.0.0.0 網(wǎng)段的用戶,能夠通過代理服務(wù)器訪問到后端的172.16.1.7 的 8080 端口站點(diǎn)內(nèi)容
[root@lb01 ~]# cd /etc/nginx/conf.d/
[root@lb01 conf.d]# cat proxy_web_node1.conf
server {
listen 80;
server_name nginx.oldboy.com;
location / {
proxy_pass http://172.16.1.7:8080;
include proxy_params;
}
}
[root@lb01 conf.d]# systemctl enable nginx
[root@lb01 conf.d]# systemctl start nginx
第二章 負(fù)載均衡
Nginx負(fù)載均衡概述
為什么需要負(fù)載均衡
我們的 Web 服務(wù)器直接面向用戶,往往要承載大量并發(fā)請(qǐng)求,單臺(tái)服務(wù)器難以負(fù)荷,我使用多臺(tái) WEB 服務(wù)器組成集群,前端使用 Nginx 負(fù)載均衡,將請(qǐng)求分散的打到我們的后端服務(wù)器集群中,實(shí)現(xiàn)負(fù)載的分發(fā)。那么會(huì)大大提升系統(tǒng)的吞吐率、請(qǐng)求性能、高容災(zāi)

往往我們接觸的最多的是 SLB(Server Load Balance)負(fù)載均衡,實(shí)現(xiàn)最多的也是 SLB、那么 SLB 它的調(diào)度節(jié)點(diǎn)和服務(wù)節(jié)點(diǎn)通常是在一個(gè)地域里面。那么它在這個(gè)小的邏輯地域里面決定了他對(duì)部分服務(wù)的實(shí)時(shí)性、響應(yīng)性是非常好的。
所以說當(dāng)海量用戶請(qǐng)求過來以后,它同樣是請(qǐng)求調(diào)度節(jié)點(diǎn),調(diào)度節(jié)點(diǎn)將用戶的請(qǐng)求轉(zhuǎn)發(fā)給后端對(duì)應(yīng)的服務(wù)節(jié)點(diǎn),服務(wù)節(jié)點(diǎn)處理完請(qǐng)求后在轉(zhuǎn)發(fā)給調(diào)度節(jié)點(diǎn),調(diào)度節(jié)點(diǎn)最后響應(yīng)給用戶節(jié)點(diǎn)。這樣也能實(shí)現(xiàn)一個(gè)均衡的作用,那么Nginx 則是一個(gè)典型的 SLB
Nginx負(fù)載均衡配置場景
1.四層負(fù)載均衡
所謂四層負(fù)載均衡指的是 OSI 七層模型中的傳輸層,那么傳輸層 Nginx 已經(jīng)能支持 TCP/IP 的控制,所以只需要對(duì)客戶端的請(qǐng)求進(jìn)行 TCP/IP 協(xié)議的包轉(zhuǎn)發(fā)就可以實(shí)現(xiàn)負(fù)載均衡,那么它的好處是性能非???、只需要底層進(jìn)行應(yīng)用處理,而不需要進(jìn)行一些復(fù)雜的邏輯

2.七層負(fù)載均衡
七層負(fù)載均衡它是在應(yīng)用層,那么它可以完成很多應(yīng)用方面的協(xié)議請(qǐng)求,比如我們說的 http 應(yīng)用的負(fù)載均衡,它可以實(shí)現(xiàn) http 信息的改寫、頭信息的改寫、安全應(yīng)用規(guī)則控制、 URL 匹配規(guī)則控制、以及轉(zhuǎn)發(fā)、 rewrite 等等的規(guī)則,所以在應(yīng)用層的服務(wù)里面,我們可以做的內(nèi)容就更多,那么 Nginx 則是一個(gè)典型的七層負(fù)載均衡 SLB

3.四層負(fù)載均衡與七層負(fù)載均衡區(qū)別
四層負(fù)載均衡數(shù)據(jù)包在底層就進(jìn)行了分發(fā),而七層負(fù)載均衡數(shù)據(jù)包則是在最頂層進(jìn)行分發(fā)、由此可以看出,七層負(fù)載均衡效率沒有四負(fù)載均衡高。
但七層負(fù)載均衡更貼近于服務(wù),如:http 協(xié)議就是七層協(xié)議,我們可以用 Nginx 可以作會(huì)話保持, URL 路徑規(guī)則匹配、 head 頭改寫等等,這些是四層負(fù)載均衡無法實(shí)現(xiàn)的
Nginx負(fù)載均衡調(diào)度算法

Nginx負(fù)載均衡配置參數(shù)

Nginx反向代理負(fù)載均衡關(guān)系圖

Nginx負(fù)載均衡實(shí)戰(zhàn)
1.規(guī)劃分類
/upload 10.0.0.8:80 upload服務(wù)器
/static 10.0.0.7:80 static靜態(tài)服務(wù)器
/ 10.0.0.9:80 默認(rèn)服務(wù)器
2.創(chuàng)建地址池
upstream upload_pools{
server 10.0.0.8:80;
}
upstream static_pools{
server 10.0.0.7:80;
}
upstream defaule_pools{
server 10.0.0.9:80;
}
3.匹配條件
location /static/ {
proxy_pass http://static_pools;
include proxy_params;
}
###將符合upload的請(qǐng)求交給上傳服務(wù)器池upload_pools,配置如下
location /upload/ {
proxy_pass http://upload_pools;
include proxy_params;
}
###不符合上述規(guī)則的請(qǐng)求,默認(rèn)全交給動(dòng)態(tài)服務(wù)器池default_pools,配置如下:
location / {
proxy_pass http://default_pools;
include proxy_params;
}
4.組合在一起
[root@lb01 ~]# cat /etc/nginx/conf.d/node_proxy.conf
upstream upload_pools {
server 10.0.0.8:80;
}
upstream static_pools {
server 10.0.0.7:80;
}
upstream default_pools {
server 10.0.0.9:80;
}
server {
listen 80;
server_name www.oldboy.com;
location /static/ {
proxy_pass http://static_pools;
include proxy_params;
}
location /upload/ {
proxy_pass http://upload_pools;
include proxy_params;
}
location / {
proxy_pass http://default_pools;
include proxy_params;
}
}
5.創(chuàng)建代碼環(huán)境
每個(gè)虛擬機(jī)存放的網(wǎng)頁路徑
www.oldboy.com/index.html
www.oldboy.com/upload/index.html
www.oldboy.com/static/index.html
創(chuàng)建目錄及測試頁面命令
mkdir -p /data/html/www/{upload,static}
echo "$(hostname) default" >/data/html/www/index.html
echo "$(hostname) upload" >/data/html/www/upload/index.html
echo "$(hostname) static" >/data/html/www/static/index.html
6.進(jìn)行測試
[root@lb01 ~]# curl www.oldboy.com/index.html
sweb01 default
[root@lb01 ~]# curl www.oldboy.com/static/
web01 static
[root@lb01 ~]# curl www.oldboy.com/upload/
web02 upload
第三章 根據(jù)條件轉(zhuǎn)發(fā)實(shí)戰(zhàn)
3.1 根據(jù)文件類型轉(zhuǎn)發(fā)
轉(zhuǎn)發(fā)需求
只需修改nginx.conf的配置文件中的loaction區(qū)塊代碼即可
lb配置文件
location ~ .*.(gif|jpg|jpeg|png|bmp|swf|css|js)$ {
proxy_pass http://static_pools;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
upstream server_pools {
server 10.0.0.7 weight=1 max_fails=3 fail_timeout=10s;
server 10.0.0.8 weight=1 max_fails=3 fail_timeout=10s;
server 10.0.0.9 weight=1 max_fails=3 fail_timeout=10s;
}
3.2 動(dòng)靜分離
轉(zhuǎn)發(fā)需求
動(dòng)態(tài)資源轉(zhuǎn)發(fā)到php服務(wù)器
靜態(tài)資源轉(zhuǎn)發(fā)到靜態(tài)服務(wù)器
配置文件
[root@lb01 /etc/nginx/conf.d]# cat ds_proxy.conf
root@lb01 conf.d]# cat ds_proxy.conf
upstream static {
server 10.0.0.7:80;
}
upstream php {
server 10.0.0.8:8080;
}
server {
listen 80;
server_name ds.oldboy.com;
location / {
root /code;
index index.html;
}
location ~ .*\.(png|jpg|gif)$ {
proxy_pass http://static;
include proxy_params;
}
location ~ .*\.php$ {
proxy_pass http://php;
include proxy_params;
}
}
3.3 根據(jù)客戶端轉(zhuǎn)發(fā)
轉(zhuǎn)發(fā)需求
手機(jī)和電腦 訪問相同的網(wǎng)站----結(jié)果不同
lb服務(wù)器配置文件
[root@lb01 conf.d]# cat sj.conf
upstream iphone {
server 172.16.1.7:9091;
}
upstream android {
server 172.16.1.7:9090;
}
upstream pc {
server 172.16.1.7:9092;
}
server {
listen 80;
server_name sj.oldboy.com;
location / {
#默認(rèn)跳轉(zhuǎn)至 pc 站點(diǎn)
proxy_pass http://pc;
include proxy_params;
#如果客戶端是 Iphone 則跳轉(zhuǎn)到 iphone 的資源池
if ($http_user_agent ~* "Iphone") {
proxy_pass http://iphone;
}
#如果客戶端是 Android 則跳轉(zhuǎn)到 android 的資源池
if ($http_user_agent ~* "Android"){
proxy_pass http://android;
}
#如果客戶端是 IE 瀏覽器,則返回 403 錯(cuò)誤。
if ($http_user_agent ~* "msie"){
return 403;
}
}
}
web服務(wù)器配置
[root@web01 conf.d]# cat sj.conf
server {
listen 9090;
location / {
root /code/android;
index index.html;
}
}
server {
listen 9091;
location / {
root /code/iphone;
index index.html;
}
}
server {
listen 9092;
location / {
root /code/pc;
index index.html;
}
}
[root@web01 conf.d]# mkdir -p /code/{android,iphone,pc}
[root@web01 conf.d]# echo "PC" > /code/pc/index.html
[root@web01 conf.d]# echo "Iphone" > /code/iphone/index.html
[root@web01 conf.d]# echo "Android" > /code/android/index.html
[root@web01 conf.d]# systemctl restart nginx
訪問測試
[root@lb01 conf.d]# curl -A "chrome" sj.oldboy.com
PC
[root@lb01 conf.d]# curl -A "iphone" sj.oldboy.com
Iphone
[root@lb01 conf.d]# curl -A "android" sj.oldboy.com
Android