Nginx 是一個高效能的HTTP和反向代理伺服器,同時也是一個 IMAP/POP3/SMTP 代理伺服器。
常見場景:
- 靜態資源伺服器
- 動態匹配
- 反向代理
- Gzip 壓縮
- 負載均衡
先來看下預設的Nginx配置,我將以此為基礎依次介紹Nginx的用法
Nginx 安裝目錄下的
nginx.conf
就是Nginx全域性的配置檔案,我們主要修改這裡的內容。nginx.conf.default
作為配置檔案的備份。
# 設定工作程式的數量
worker_processes 1;
# 處理連線
events {
# 設定連線數
worker_connections 1024;
}
http {
# 檔案擴充名查詢集合
include mime.types;
# 當查詢不到對應型別的時候預設值
default_type application/octet-stream;
# 日誌格式,定義別名為 main
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
# 指定日誌輸入目錄
#access_log logs/access.log main;
# 呼叫 sendfile 系統傳輸檔案
sendfile on;
#tcp_nopush on;
# 客戶端與伺服器連線超時時間,超時自動斷開
#keepalive_timeout 0;
keepalive_timeout 65;
# 開啟gizip 壓縮
#gzip on;
# 虛擬主機
server {
listen 8080;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
# 路由
location / {
root html;
index index.html index.htm;
}
}
# 引入其他的配置檔案
include servers/*;
}
複製程式碼
搭建靜態站點
# 虛擬主機server塊
server {
# 埠
listen 8080;
# 匹配請求中的host值
server_name localhost;
# 監聽請求路徑
location / {
# 查詢目錄
root /source;
# 預設查詢
index index.html index.htm;
}
}
複製程式碼
這裡說明一下相關欄位
server
配置虛擬主機的相關引數,可以有多個server_name
通過請求中的host值 找到對應的虛擬主機的配置location
配置請求路由,處理相關頁面情況root
查詢資源的路徑
配置完成後執行 nginx -t
看是否有錯誤,如果看到的是下面這種就是成功了
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
複製程式碼
然後執行nginx -s reload
更新Nginx配置檔案
這時候開啟瀏覽器 輸入 localhost:8080 應該就能看到你的頁面了
nginx -t
檢查配置檔案是否有語法錯誤
nginx -s reload
向主程式傳送訊號,重新載入配置檔案
nginx -s stop
快速關閉
nginx -s quit
等待工作程式處理完成後關閉
動態匹配(請求過濾)
通常在開發環境或者測試環境的時候呢我們修改了程式碼,因為瀏覽器快取,可能不會生效,需要手動清除快取,才能看到修改後的效果,這裡我們做一個配置讓瀏覽器不快取相關的資源。
location ~* \.(js|css|png|jpg|gif)$ {
add_header Cache-Control no-store;
}
複製程式碼
~* \.(js|css|png|jpg|gif)$
是匹配以相關檔案型別然後單獨處理。
add_header
是給請求的響應加上一個頭資訊Cache-Control no-store
,告知瀏覽器禁用快取,每次都從伺服器獲取
效果如下:
匹配規則
通常的形式如下
location = / {
[ configuration A ]
}
location / {
[ configuration B ]
}
location /documents/ {
[ configuration C ]
}
location ^~ /images/ {
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
[ configuration E ]
}
複製程式碼
=
表示精確匹配。只有請求的url路徑與後面的字串完全相等時,才會命中(優先順序最高)。^~
表示如果該符號後面的字元是最佳匹配,採用該規則,不再進行後續的查詢。~
表示該規則是使用正則定義的,區分大小寫。~*
表示該規則是使用正則定義的,不區分大小寫。
當然我們還可以通過狀態碼來過濾請求就像這樣
# 通過狀態碼,返回指定的錯誤頁面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /source/error_page;
}
複製程式碼
反向代理解決跨域
因為瀏覽器的同源策略,當前端域名與後端域名不一致的時候導致請求失敗。我們可以通過配置Nginx反向代理來解決。
location /api {
# 請求host傳給後端
proxy_set_header Host $http_host;
# 請求ip 傳給後端
proxy_set_header X-Real-IP $remote_addr;
# 請求協議傳給後端
proxy_set_header X-Scheme $scheme;
# 路徑重寫
rewrite /api/(.*) /$1 break;
# 代理伺服器
proxy_pass http://localhost:9000;
}
複製程式碼
- 攔截路徑
/api
, 可以通過正則匹配。 proxy_set_header
允許重新定義或新增欄位傳遞給代理伺服器的請求頭。$http_host
、$remote_addr
、$scheme
為Nginx內建變數。rewrite
根據rewrite後的請求URI,將路徑重寫,如:介面路徑為/user
, 我們可以請求/api/user
。(為什麼需要重寫uri?因為在使用Nginx做反向代理的時候,需要匹配到跨域的介面再做轉發,為了方便匹配,會人為的在原介面中新增一段路徑(或標示, 如例子中的api
),因此需要在匹配之後、轉發之前把新增的那段去掉,因此需要rewrite。)break
繼續本次請求後面的處理 ,停止匹配下面的location
。需要注意的是與之類似的last
執行過程則是停止當前這個請求,並根據rewrite匹配的規則重新發起一個請求,從上到下依次匹配location
後面的規則。proxy_pass
代理伺服器。
原理:Nginx攔截到相關匹配規則, Nginx再將請求轉發到
http://localhost:9000
,Nginx得到請求後再響應到前端,可以直接請求/api/user
完成請求。
配置Gzip
開發過程中難免用到一些成熟的框架,或者外掛,這些外部的依賴,有時候體積比較大,導致頁面響應緩慢,我們可以用打包工具(webpack, rollup),將程式碼進行壓縮,以縮小程式碼體積。 開啟Nginx Gzip壓縮功能。需要注意的是 Gzip 壓縮功能需要瀏覽器跟伺服器都支援,即伺服器壓縮,瀏覽器解析。
- 檢視瀏覽器支援情況,確定 請求頭 中的
Accept-Encoding
欄位
- 確定瀏覽器支援,我們就可以在Nginx中配置
server {
# 開啟gzip 壓縮
gzip on;
# 設定gzip所需的http協議最低版本 (HTTP/1.1, HTTP/1.0)
gzip_http_version 1.1;
# 設定壓縮級別,壓縮級別越高壓縮時間越長 (1-9)
gzip_comp_level 4;
# 設定壓縮的最小位元組數, 頁面Content-Length獲取
gzip_min_length 1000;
# 設定壓縮檔案的型別 (text/html)
gzip_types text/plain application/javascript text/css;
}
複製程式碼
- 檢視配置是否生效,檢視 響應頭 中的
Content-Encoding
欄位,值為gzip
負載均衡
負載均衡是Nginx 比較常用的一個功能,可優化資源利用率,最大化吞吐量,減少延遲,確保容錯配置,將流量分配到多個後端伺服器。
Syntax: upstream name { ... }
Default: —
Context: stream
複製程式碼
這裡舉出常用的幾種策略
- 輪詢(預設),請求過來後,Nginx 隨機分配流量到任一伺服器
upstream backend {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
}
複製程式碼
weight=number
設定伺服器的權重,預設為1,權重大的會被優先分配
upstream backend {
server 127.0.0.1:3000 weight=2;
server 127.0.0.1:3001 weight=1;
}
複製程式碼
backup
標記為備份伺服器。當主伺服器不可用時,將傳遞與備份伺服器的連線。
upstream backend {
server 127.0.0.1:3000 backup;
server 127.0.0.1:3001;
}
複製程式碼
ip_hash
保持會話,保證同一客戶端始終訪問一臺伺服器。
upstream backend {
ip_hash;
server 127.0.0.1:3000 backup;
server 127.0.0.1:3001;
}
複製程式碼
least_conn
優先分配最少連線數的伺服器,避免伺服器超載請求過多。
upstream backend {
least_conn;
server 127.0.0.1:3000;
server 127.0.0.1:3001;
}
複製程式碼
當我們需要代理一個叢集時候可以通過下面這種方式實現
http {
upstream backend {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
}
...
server {
listen 9000;
server_name localhost;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_pass backend;
}
}
}
複製程式碼
最後
Nginx 的功能還有很多,這裡只介紹了幾個比較基礎、常用的,供大家學習和參考,快速入門,搭建出一套可用的環境。