Nginx詳解

nginx詳解

一、什么是正向代理和反向代理?


  • 正向代理

    image
    • 反向代理

      image

URI、URL和URN:

  • URI :Uniform Resource Identifier,統(tǒng)一資源標識符;

  • URL:Uniform Resource Locator,統(tǒng)一資源定位符;

  • URN:Uniform Resource Name,統(tǒng)一資源名稱。

image
  • URL主要由三部分組成:第一部分是協(xié)議(或成為服務(wù)方式),第二部分是存有該資源的主機IP地址(有時也包括端口號),第三部分是主機資源的具體地址,如目錄和文件夾名等。

  • URI和URL都定義了資源是什么,但URL是一種具體的URI,它不僅唯一標識資源,而且還提供了定位該資源的信息。URI 是一種語義上的抽象概念,可以是絕對的,也可以是相對的,而URL則必須提供足夠的信息來定位,是絕對的。

二、nginx負載均衡策略


nginx服務(wù)器負載均衡策略可以劃分為兩大類:

1.內(nèi)置策略

  • 輪詢:將每個前端請求按順序(時間順序或者排列順序)逐一分配到不同的后端節(jié)點上,對于出現(xiàn)問題的后端節(jié)點自動排除;

  • 加權(quán)輪詢:在輪詢的基礎(chǔ)上加上weight,指定各后端節(jié)點被輪詢到的幾率;

  • IP_hash:將前端訪問的IP進行hash操作,然后根據(jù)hash結(jié)果將請求分配給不同的后端節(jié)點上。注:同一IP經(jīng)過hash的出來的值是一樣的,即請求固定落在hash后選擇的那臺后端服務(wù)器上。

2.擴展策略

  • url_hash:對前端訪問的url進行hash操作。(若后端服務(wù)器異常,不能自動排除該節(jié)點)

  • fair:將請求轉(zhuǎn)發(fā)到一個最近負載最小的后臺節(jié)點。如何判斷負載最???Nginx通過后端節(jié)點對請求的響應(yīng)時間來判斷負載的情況。響應(yīng)時間短的節(jié)點負載相對較輕。

三、nginx基本配置詳解


##### **1.nginx.conf**:

worker_processes 1;
error_log  /usr/local/nginx/logs/nginx_error.log;
pid /usr/local/nginx/nginx.pid;
events{
 worker_connections 1024;
}
?
http{
 include mime.types;
 default_type application/octet-stream;

 sendfile on;
 keepalive_timeout 65;

 upstream  back{
 server address weight=2 max_fails=5 fail_timeout=30s;
 server address weight=1 max_fails=5 fail_timeout=30s;
 ip_hash;
 }

 server{
 listen 80;
 server_name localhost;

 location / {
 index index.html index.php;
 root /usr/local/nginx/html;
 }

 location ~ /api/1.0/ll/(.*) {
 proxy_pass http://back; # 設(shè)置被代理服務(wù)器地址
 proxy_set_header Host $host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 }

 error_page 404      /404.html;
 error_page 500 502 503 504 /50x.html;
 location = /50x.html{
 root html;
 }
 }

}
2.upstream 中server指令語法如下

server address [parameters] 注: 關(guān)鍵字server為必選項,address也為必選項,可以是主機名、域名、ip或 unix socket,也可以指定端口號; ? parameters是可選參數(shù),可以是如下參數(shù):

  • down:將server標記為宕機狀態(tài);

  • backup:將組內(nèi)服務(wù)器標記為備用服務(wù)器,只有當正常的服務(wù)器處于宕機狀態(tài)或則繁忙狀態(tài)時,該服務(wù)器才會被用來處理客戶端請求;

  • weight:表示server的負載權(quán)重,權(quán)重越大被請求的幾率越大,默認為1;

  • fail_timeout:請求時間超過這個值時,認定其為請求失敗,此時斷開連接,默認值為10s;

  • max_fails:設(shè)置一個請求失敗的次數(shù),在一定范圍時間內(nèi)(即fail_timeout時間內(nèi)),當對組內(nèi)某臺服務(wù)器請求失敗的次數(shù)超過該變量設(shè)置的值時,認為該服務(wù)器無效,默認值是1(即默認情況下只要發(fā)生錯誤就認為server宕機了);

  • fail_timeout和max_fails通常聯(lián)合使用:如果某臺server在fail_timeout時間內(nèi)出現(xiàn)了max_fails次連接失敗,那么Nginx會認為該server已經(jīng)宕機,從而在fail_timeout時間內(nèi)不會再去請求這臺server。

3.location用法:

location 模式 含義
以 = 開頭 表示精準匹配,如只匹配根目錄結(jié)尾的請求,后面不能帶任何字符串
以 ^~ 開頭 表示uri以某個常規(guī)字符串開頭,不是正則匹配
以 ~ 開頭 表示區(qū)分大小寫的正則匹配
以 ~* 開頭 表示不區(qū)分大小寫的正則匹配
以 / 開頭 通用匹配, 如果沒有其它匹配,任何請求都會匹配到

1)精準匹配 /,主機名后面不能帶任何字符串

location = / {
      [configuration A]
}

2)通用匹配,所有地址都以/開頭,所以這條規(guī)則將會在最后匹配,即默認請求

 location / {
    [configuration B]
}

3)匹配以 /test/ 開頭的地址,匹配符合以后,還要繼續(xù)往下搜索。只有后面的正則表達式?jīng)]有匹配到時,這一條才會采用(該普通匹配遵循最長匹配規(guī)則),即若uri為/test/mine/則會采用第二條的配置

location /test/ {
  [configuration C]
}
location /test/mine/ {
 #配置
}

4)匹配任何以/images/開頭的地址,匹配符合以后,停止往下搜索正則

location ^~ /images/ {
  [configuration D]
}

5)匹配所有以gif、jpg或jpeg結(jié)尾的請求。需要注意的是,若配置了4中的配置,則/images/下的圖片都只會被配置D處理,因為^~不再往下搜索

location ~* \.(gif|jpg|jpeg)$ {
  [configuration E]
}

6)各匹配順序優(yōu)先級如下

(location =) > (location 完整路徑) > (location ^~ 路徑)> (location ~,~*正則順序) > (location 部分起始路徑) > (/)

7)測試時的configuration推薦使用以下配置來測試,可以配置不同的rewrite網(wǎng)址來達到測試效果,如下所示。在瀏覽器中輸入ip+端口號/test/即可測試匹配是否成功。

location /test/ {
   rewrite ^ https://jeryliang.github.io/;
}

8)若使用location來實現(xiàn)訪問靜態(tài)文件的話,有以下需要注意的地方

例:該例子就是訪問nginx默認的index.html
默認配置為:
location / {
index index.html;
root /usr/local/nginx/html;
}
修改后的配置:
location /html/ {
 index index.html;
 root /usr/local/nginx/; 
}

以上兩個配置都能實現(xiàn)訪問nginx默認的index.html。這是為什么呢?修改后的配置通過請求ip:port/html/也可以訪問,是因為匹配字符串html會和root指定路徑進行拼接,實際的拼接后的路徑為/usr/local/nginx/html。
而默認的其實也是拼接的,只不過匹配字符串為/,拼接后和原始/usr/local/nginx/html是一樣的,所以訪問到了index.html。

4.nginx中的rewrite實現(xiàn)域名跳轉(zhuǎn)

在開始講述rewrite功能前,需要搞清楚"地址重寫"和"地址轉(zhuǎn)發(fā)"兩個概念。(注:rewrite功能依賴于PCRE庫)

  • 地址重寫:其實也就是地址重定向,例:輸入google.cn訪問谷歌時,在被服務(wù)器重定向為www.google.com的過程就是地址重定向的過程,此時瀏覽器的地址會變?yōu)?a target="_blank">www.google.com;

  • 地址轉(zhuǎn)發(fā):是指一個域名指指到另一個已有站點的過程。

這兩者的主要區(qū)別如下:

  • 地址轉(zhuǎn)發(fā)后客戶端瀏覽器地址欄中的地址是不會改變的,而地址重寫后的客戶端瀏覽器地址欄中的地址改變?yōu)榉?wù)器選擇確定的地址;

  • 在一次地址轉(zhuǎn)發(fā)過程中,只產(chǎn)生一次網(wǎng)絡(luò)請求,而地址重寫一般會產(chǎn)生兩次或兩次以上的請求;

  • 地址轉(zhuǎn)發(fā)的速度比地址重定向快。

rewrite可以在server塊或者location塊中配置,以下為幾個例子:

# 例1:域名跳轉(zhuǎn)
server {
 listen 80;
 server_name liang.jerry.com;
 rewrite ^/ http://www.jerry.info/;
}
# 例2:多域名跳轉(zhuǎn)
server {
 listen 80;
 server_name  liang.jerry.name  liang.jerry.info;
 index index.htm index.php;
 root /usr/local/html;
 if($host  ~ jerry\.info){    # $host的值中是否包含(其中~對大小寫敏感)jerry.info字符串,若                             #包含則為真
 rewrite ^(.*) http://liang.jerry.name/$1 permanent; 
 #^為匹配字符串的開始,(.*)匹配任意字符,permanent表示返回301永久重定向,地址欄會顯示跳轉(zhuǎn)后的地址;
 }
}
# 例3:三級域名跳轉(zhuǎn)
server {
 listen 80;
 server_name liang1.jerry.name liang2.jerry.name;
 # ~*對字母大小寫不敏感,若$http_host中包含 任意字符.jerry.name字符串,則為真
 if($host ~*  ^(.*)\.jerry\.name$){
 rewrite ^(.*) http://liang.jerry.name$1;
 break; # 此處break目的在于重定向后不再進行l(wèi)ocation的匹配(即后續(xù)的其他rewrite),
 }
}

5.rewrite常用正則

.  匹配除換行符以外的任意字符
? 重復(fù)0次或1次
+  重復(fù)1次或更多次
*  重復(fù)0次或更多次
\d 匹配數(shù)字
^  匹配字符串的開始
$  匹配字符串的結(jié)束
{n} 重復(fù)n次
{n,} 重復(fù)n次或更多次
[c]  匹配單個字符c
[a-z] 匹配a-z小寫字母的任意一個
小括號()之間匹配的內(nèi)容,可以在后面通過$1來引用,$2表示的是前面第二個()里的內(nèi)容,同時還有轉(zhuǎn)義字符\
5.反向代理服務(wù)需要注意的細節(jié)

proxy_pass指令,先看如下例子:

# 例1
upstream  proxy_svrs {
 server http://192.168.1.1:8088/uri/;
 server http://192.168.1.1:8088/uri/;
 server http://192.168.1.1:8088/uri/;
}
server {
 listen 80;
 server_name www.jerry.com;
 location / {
 proxy_pass  proxy_svrs;
 }
}
# 例2
upstream proxy_svrs {
 server 192.168.1.1:8088/uri/;
 server 192.168.1.1:8088/uri/;
 server 192.168.1.1:8088/uri/;
}
server {
 listen 80;
 server_name www.jerry.com;
 location / {
 proxy_pass  http://proxy_svrs;
 }
}

即在服務(wù)器組中已經(jīng)指明了傳輸協(xié)議"http://"時,proxy_pass中就不需要指明,反之,要在proxy_pass中指明。

需要注意的是如下的情況:

server proxy_svrs {
 listen 80;
 server_name www.jerry.com;
 location /server/ {
 proxy_pass http://192.168.1.2/jerry/;
 }
}

在這配置的情況下,假如客戶端發(fā)起的請求為http://www.jerry.com/server/,Nginx會把地址轉(zhuǎn)向"http://192.168.1.2/jerry/"。所以,在使用proxy_pass代理的時候,如果不想改變原有地址中的URI,就不要在URL中配置URI。同時,需要注意的是"/"同樣是作為URI,如http://192.168.1.2http://182.168.1.2/是有區(qū)別的,若代理的URL中包含URI,第二種會替換掉原有URL中的URI。如下:

server {
 listen 80;
 server_name www.jerry.com;
 location /server/ {
 # 配置1:   proxy_pass  http://192.168.1.2;
 # 配置2:   proxy_pass  http://192.168.1.2/;
 }
}

proxy_set_header指令

該指令可以更改Nginx服務(wù)器接收到的客戶端請求的請求頭信息,然后將新的請求頭發(fā)送給被代理的服務(wù)器。其語法結(jié)構(gòu)為:

proxy_set_header field value;
# field為要更改的信息所在的頭域;
# value為更改的值,支持使用文本、變量或者變量的組合
#例1
proxy_set_header Host $http_host; #將目前Host頭域的值填充成客戶端的地址
proxy_set_header Host $host; #將當前l(fā)ocation塊的server_name指令值填充到Host頭域

proxy_http_version指令

該指令用于設(shè)置Nginx服務(wù)器提供代理服務(wù)的HTTP協(xié)議版本,默認設(shè)置為1.0版本。1.1版本支持upstream服務(wù)器組設(shè)置中的keepalive指令。

proxy_http_version 1.0  | 1.1;

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容