萬字總結,體系化帶你全面認識 Nginx !
前言
作為一名開發(fā)人員,你是不是經(jīng)常碰到領導讓你上服務器去修改 Nginx 配置,然而你可能會對這些配置并不熟悉!今天就讓我們一起告別這種尷尬,向“真正”的程序員邁進!!!
如果本文對你有所幫助,請點個?? ?? ?? 吧!
Nginx 概述

Nginx 是開源、高性能、高可靠的 Web 和反向代理服務器,而且支持熱部署,幾乎可以做到 7 * 24 小時不間斷運行,即使運行幾個月也不需要重新啟動,還能在不間斷服務的情況下對軟件版本進行熱更新。性能是 Nginx 最重要的考量,其占用內(nèi)存少、并發(fā)能力強、能支持高達 5w 個并發(fā)連接數(shù),最重要的是, Nginx 是免費的并可以商業(yè)化,配置使用也比較簡單。
Nginx 特點
高并發(fā)、高性能; 模塊化架構使得它的擴展性非常好; 異步非阻塞的事件驅動模型這點和 Node.js相似;相對于其它服務器來說它可以連續(xù)幾個月甚至更長而不需要重啟服務器使得它具有高可靠性; 熱部署、平滑升級; 完全開源,生態(tài)繁榮;
Nginx 作用
Nginx 的最重要的幾個使用場景:
靜態(tài)資源服務,通過本地文件系統(tǒng)提供服務; 反向代理服務,延伸出包括緩存、負載均衡等; API服務,OpenResty;
對于前端來說 Node.js 并不陌生, Nginx 和 Node.js 的很多理念類似, HTTP 服務器、事件驅動、異步非阻塞等,且 Nginx 的大部分功能使用 Node.js 也可以實現(xiàn),但 Nginx 和 Node.js 并不沖突,都有自己擅長的領域。Nginx 擅長于底層服務器端資源的處理(靜態(tài)資源處理轉發(fā)、反向代理,負載均衡等), Node.js 更擅長上層具體業(yè)務邏輯的處理,兩者可以完美組合。
用一張圖表示:
Nginx 安裝
本文演示的是 Linux centOS 7.x 的操作系統(tǒng)上安裝 Nginx ,至于在其它操作系統(tǒng)上進行安裝可以網(wǎng)上自行搜索,都非常簡單的。
使用 ?yum 安裝 Nginx :
yum?install?nginx?-y
復制代碼
安裝完成后,通過 rpm -ql nginx 命令查看 Nginx 的安裝信息:
#?Nginx配置文件
/etc/nginx/nginx.conf?#?nginx?主配置文件
/etc/nginx/nginx.conf.default
#?可執(zhí)行程序文件
/usr/bin/nginx-upgrade
/usr/sbin/nginx
#?nginx庫文件
/usr/lib/systemd/system/nginx.service?#?用于配置系統(tǒng)守護進程
/usr/lib64/nginx/modules?#?Nginx模塊目錄
#?幫助文檔
/usr/share/doc/nginx-1.16.1
/usr/share/doc/nginx-1.16.1/CHANGES
/usr/share/doc/nginx-1.16.1/README
/usr/share/doc/nginx-1.16.1/README.dynamic
/usr/share/doc/nginx-1.16.1/UPGRADE-NOTES-1.6-to-1.10
#?靜態(tài)資源目錄
/usr/share/nginx/html/404.html
/usr/share/nginx/html/50x.html
/usr/share/nginx/html/index.html
#?存放Nginx日志文件
/var/log/nginx
復制代碼
主要關注的文件夾有兩個:
/etc/nginx/conf.d/是子配置項存放處,/etc/nginx/nginx.conf主配置文件會默認把這個文件夾中所有子配置項都引入;/usr/share/nginx/html/靜態(tài)文件都放在這個文件夾,也可以根據(jù)你自己的習慣放在其他地方;
Nginx 常用命令
systemctl 系統(tǒng)命令:
#?開機配置
systemctl?enable?nginx?#?開機自動啟動
systemctl?disable?nginx?#?關閉開機自動啟動
#?啟動Nginx
systemctl?start?nginx?#?啟動Nginx成功后,可以直接訪問主機IP,此時會展示Nginx默認頁面
#?停止Nginx
systemctl?stop?nginx
#?重啟Nginx
systemctl?restart?nginx
#?重新加載Nginx
systemctl?reload?nginx
#?查看?Nginx?運行狀態(tài)
systemctl?status?nginx
#?查看Nginx進程
ps?-ef?|?grep?nginx
#?殺死Nginx進程
kill?-9?pid?#?根據(jù)上面查看到的Nginx進程號,殺死Nginx進程,-9?表示強制結束進程
復制代碼
Nginx 應用程序命令:
nginx?-s?reload??#?向主進程發(fā)送信號,重新加載配置文件,熱重啟
nginx?-s?reopen??#?重啟?Nginx
nginx?-s?stop????#?快速關閉
nginx?-s?quit????#?等待工作進程處理完成后關閉
nginx?-T?????????#?查看當前?Nginx?最終的配置
nginx?-t?????????#?檢查配置是否有問題
復制代碼
Nginx 核心配置
配置文件結構
Nginx 的典型配置示例:
#?main段配置信息
user??nginx;????????????????????????#?運行用戶,默認即是nginx,可以不進行設置
worker_processes??auto;?????????????#?Nginx?進程數(shù),一般設置為和?CPU?核數(shù)一樣
error_log??/var/log/nginx/error.log?warn;???#?Nginx?的錯誤日志存放目錄
pid????????/var/run/nginx.pid;??????#?Nginx?服務啟動時的?pid?存放位置
#?events段配置信息
events?{
????use?epoll;?????#?使用epoll的I/O模型(如果你不知道Nginx該使用哪種輪詢方法,會自動選擇一個最適合你操作系統(tǒng)的)
????worker_connections?1024;???#?每個進程允許最大并發(fā)數(shù)
}
#?http段配置信息
#?配置使用最頻繁的部分,代理、緩存、日志定義等絕大多數(shù)功能和第三方模塊的配置都在這里設置
http?{?
????#?設置日志模式
????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??/var/log/nginx/access.log??main;???#?Nginx訪問日志存放位置
????sendfile????????????on;???#?開啟高效傳輸模式
????tcp_nopush??????????on;???#?減少網(wǎng)絡報文段的數(shù)量
????tcp_nodelay?????????on;
????keepalive_timeout???65;???#?保持連接的時間,也叫超時時間,單位秒
????types_hash_max_size?2048;
????include?????????????/etc/nginx/mime.types;??????#?文件擴展名與類型映射表
????default_type????????application/octet-stream;???#?默認文件類型
????include?/etc/nginx/conf.d/*.conf;???#?加載子配置項
????
????#?server段配置信息
????server?{
?????listen???????80;???????#?配置監(jiān)聽的端口
?????server_name??localhost;????#?配置的域名
??????
?????#?location段配置信息
?????location?/?{
??????root???/usr/share/nginx/html;??#?網(wǎng)站根目錄
??????index??index.html?index.htm;???#?默認首頁文件
??????deny?172.168.22.11;???#?禁止訪問的ip地址,可以為all
????? allow 172.168.33.44;#?允許訪問的ip地址,可以為all
?????}
?????
?????error_page?500?502?503?504?/50x.html;??#?默認50x對應的訪問頁面
?????error_page?400?404?error.html;???#?同上
????}
}
復制代碼
main全局配置,對全局生效;events配置影響Nginx服務器與用戶的網(wǎng)絡連接;http配置代理,緩存,日志定義等絕大多數(shù)功能和第三方模塊的配置;server配置虛擬主機的相關參數(shù),一個http塊中可以有多個server塊;location用于配置匹配的uri;upstream配置后端服務器具體地址,負載均衡配置不可或缺的部分;
用一張圖清晰的展示它的層級結構:
配置文件 main 段核心參數(shù)
user
指定運行 Nginx 的 woker 子進程的屬主和屬組,其中組可以不指定。
user?USERNAME?[GROUP]
user?nginx?lion;?#?用戶是nginx;組是lion
復制代碼
pid
指定運行 Nginx master 主進程的 pid 文件存放路徑。
pid?/opt/nginx/logs/nginx.pid?#?master主進程的的pid存放在nginx.pid的文件
復制代碼
worker_rlimit_nofile_number
指定 worker 子進程可以打開的最大文件句柄數(shù)。
worker_rlimit_nofile?20480;?#?可以理解成每個worker子進程的最大連接數(shù)量。
復制代碼
worker_rlimit_core
指定 worker 子進程異常終止后的 core 文件,用于記錄分析問題。
worker_rlimit_core?50M;?#?存放大小限制
working_directory?/opt/nginx/tmp;?#?存放目錄
復制代碼
worker_processes_number
指定 Nginx 啟動的 worker 子進程數(shù)量。
worker_processes?4;?#?指定具體子進程數(shù)量
worker_processes?auto;?#?與當前cpu物理核心數(shù)一致
復制代碼
worker_cpu_affinity
將每個 worker 子進程與我們的 cpu 物理核心綁定。
worker_cpu_affinity?0001?0010?0100?1000;?#?4個物理核心,4個worker子進程
復制代碼

將每個 worker 子進程與特定 CPU 物理核心綁定,優(yōu)勢在于,避免同一個 worker 子進程在不同的 CPU 核心上切換,緩存失效,降低性能。但其并不能真正的避免進程切換。
worker_priority
指定 worker 子進程的 nice 值,以調(diào)整運行 Nginx 的優(yōu)先級,通常設定為負值,以優(yōu)先調(diào)用 Nginx 。
worker_priority?-10;?#?120-10=110,110就是最終的優(yōu)先級
復制代碼
Linux 默認進程的優(yōu)先級值是120,值越小越優(yōu)先;nice 定范圍為 -20 到 +19 。
[備注] 應用的默認優(yōu)先級值是120加上 nice 值等于它最終的值,這個值越小,優(yōu)先級越高。
worker_shutdown_timeout
指定 worker 子進程優(yōu)雅退出時的超時時間。
worker_shutdown_timeout?5s;
復制代碼
timer_resolution
worker 子進程內(nèi)部使用的計時器精度,調(diào)整時間間隔越大,系統(tǒng)調(diào)用越少,有利于性能提升;反之,系統(tǒng)調(diào)用越多,性能下降。
timer_resolution?100ms;
復制代碼
在 Linux 系統(tǒng)中,用戶需要獲取計時器時需要向操作系統(tǒng)內(nèi)核發(fā)送請求,有請求就必然會有開銷,因此這個間隔越大開銷就越小。
daemon
指定 Nginx 的運行方式,前臺還是后臺,前臺用于調(diào)試,后臺用于生產(chǎn)。
daemon?off;?#?默認是on,后臺運行模式
復制代碼
配置文件 events 段核心參數(shù)
use
Nginx 使用何種事件驅動模型。
use?method;?#?不推薦配置它,讓nginx自己選擇
method 可選值為:select、poll、kqueue、epoll、/dev/poll、eventport
復制代碼
worker_connections
worker 子進程能夠處理的最大并發(fā)連接數(shù)。
worker_connections?1024?#?每個子進程的最大連接數(shù)為1024
復制代碼
accept_mutex
是否打開負載均衡互斥鎖。
accept_mutex?on?#?默認是off關閉的,這里推薦打開
復制代碼
server_name 指令
指定虛擬主機域名。
server_name?name1?name2?name3
#?示例:
server_name?www.nginx.com;
復制代碼
域名匹配的四種寫法:
精確匹配: server_name www.nginx.com;左側通配: server_name *.nginx.com;右側統(tǒng)配: server_name www.nginx.*;正則匹配: server_name ~^www\.nginx\.*$;
匹配優(yōu)先級:精確匹配 > 左側通配符匹配 > 右側通配符匹配 > 正則表達式匹配
server_name 配置實例:
1、配置本地 ?DNS 解析 vim /etc/hosts ( macOS 系統(tǒng))
#?添加如下內(nèi)容,其中?121.42.11.34?是阿里云服務器IP地址
121.42.11.34?www.nginx-test.com
121.42.11.34?mail.nginx-test.com
121.42.11.34?www.nginx-test.org
121.42.11.34?doc.nginx-test.com
121.42.11.34?www.nginx-test.cn
121.42.11.34?fe.nginx-test.club
復制代碼
[注意] 這里使用的是虛擬域名進行測試,因此需要配置本地 DNS 解析,如果使用阿里云上購買的域名,則需要在阿里云上設置好域名解析。
2、配置阿里云 Nginx ,vim /etc/nginx/nginx.conf
#?這里只列舉了http端中的sever端配置
#?左匹配
server?{
?listen?80;
?server_name?*.nginx-test.com;
?root?/usr/share/nginx/html/nginx-test/left-match/;
?location?/?{
??index?index.html;
?}
}
#?正則匹配
server?{
?listen?80;
?server_name?~^.*\.nginx-test\..*$;
?root?/usr/share/nginx/html/nginx-test/reg-match/;
?location?/?{
??index?index.html;
?}
}
#?右匹配
server?{
?listen?80;
?server_name?www.nginx-test.*;
?root?/usr/share/nginx/html/nginx-test/right-match/;
?location?/?{
??index?index.html;
?}
}
#?完全匹配
server?{
?listen?80;
?server_name?www.nginx-test.com;
?root?/usr/share/nginx/html/nginx-test/all-match/;
?location?/?{
??index?index.html;
?}
}
復制代碼
3、訪問分析
當訪問 www.nginx-test.com時,都可以被匹配上,因此選擇優(yōu)先級最高的“完全匹配”;當訪問 mail.nginx-test.com時,會進行“左匹配”;當訪問 www.nginx-test.org時,會進行“右匹配”;當訪問 doc.nginx-test.com時,會進行“左匹配”;當訪問 www.nginx-test.cn時,會進行“右匹配”;當訪問 fe.nginx-test.club時,會進行“正則匹配”;
root
指定靜態(tài)資源目錄位置,它可以寫在 http 、 server 、 location 等配置中。
root?path
例如:
location?/image?{
?root?/opt/nginx/static;
}
當用戶訪問?www.test.com/image/1.png?時,實際在服務器找的路徑是?/opt/nginx/static/image/1.png
復制代碼
[注意] root 會將定義路徑與 URI 疊加, alias 則只取定義路徑。
alias
它也是指定靜態(tài)資源目錄位置,它只能寫在 location 中。
location?/image?{
?alias?/opt/nginx/static/image/;
}
當用戶訪問?www.test.com/image/1.png?時,實際在服務器找的路徑是?/opt/nginx/static/image/1.png
復制代碼
[注意] 使用 alias 末尾一定要添加 / ,并且它只能位于 location 中。
location
配置路徑。
location?[?=?|?~?|?~*?|?^~?]?uri?{
?...
}
復制代碼
匹配規(guī)則:
=精確匹配;~正則匹配,區(qū)分大小寫;~*正則匹配,不區(qū)分大小寫;^~匹配到即停止搜索;
匹配優(yōu)先級:= > ^~ > ?~ > ~* > 不帶任何字符。
實例:
server?{
??listen?80;
??server_name?www.nginx-test.com;
??
??#?只有當訪問?www.nginx-test.com/match_all/?時才會匹配到/usr/share/nginx/html/match_all/index.html
??location?=?/match_all/?{
??????root?/usr/share/nginx/html
??????index?index.html
??}
??
??#?當訪問?www.nginx-test.com/1.jpg?等路徑時會去?/usr/share/nginx/images/1.jpg?找對應的資源
??location?~?\.(jpeg|jpg|png|svg)$?{
???root?/usr/share/nginx/images;
??}
??
??#?當訪問?www.nginx-test.com/bbs/?時會匹配上?/usr/share/nginx/html/bbs/index.html
??location?^~?/bbs/?{
???root?/usr/share/nginx/html;
????index?index.html?index.htm;
??}
}
復制代碼
location 中的反斜線
location?/test?{
?...
}
location?/test/?{
?...
}
復制代碼
不帶 /當訪問www.nginx-test.com/test時,Nginx先找是否有test目錄,如果有則找test目錄下的index.html;如果沒有test目錄,nginx則會找是否有test文件。帶 /當訪問www.nginx-test.com/test時,Nginx先找是否有test目錄,如果有則找test目錄下的index.html,如果沒有它也不會去找是否存在test文件。
return
停止處理請求,直接返回響應碼或重定向到其他 URL ;執(zhí)行 return 指令后, location 中后續(xù)指令將不會被執(zhí)行。
return?code?[text];
return?code?URL;
return?URL;
例如:
location?/?{
?return?404;?#?直接返回狀態(tài)碼
}
location?/?{
?return?404?"pages?not?found";?#?返回狀態(tài)碼?+?一段文本
}
location?/?{
?return?302?/bbs?;?#?返回狀態(tài)碼?+?重定向地址
}
location?/?{
?return?https://www.baidu.com?;?#?返回重定向地址
}
復制代碼
rewrite
根據(jù)指定正則表達式匹配規(guī)則,重寫 URL 。
語法:rewrite 正則表達式?要替換的內(nèi)容?[flag];
上下文:server、location、if
示例:rewirte /images/(.*\.jpg)$?/pic/$1;?#?$1是前面括號(.*\.jpg)的反向引用
復制代碼
flag 可選值的含義:
last重寫后的URL發(fā)起新請求,再次進入server段,重試location的中的匹配;break直接使用重寫后的URL,不再匹配其它location中語句;redirect返回302臨時重定向;permanent返回301永久重定向;
server{
??listen?80;
??server_name?fe.lion.club;?#?要在本地hosts文件進行配置
??root?html;
??location?/search?{
???rewrite?^/(.*)?https://www.baidu.com?redirect;
??}
??
??location?/images?{
???rewrite?/images/(.*)?/pics/$1;
??}
??
??location?/pics?{
???rewrite?/pics/(.*)?/photos/$1;
??}
??
??location?/photos?{
??
??}
}
復制代碼
按照這個配置我們來分析:
當訪問 fe.lion.club/search時,會自動幫我們重定向到https://www.baidu.com。當訪問 fe.lion.club/images/1.jpg時,第一步重寫URL為fe.lion.club/pics/1.jpg,找到pics的location,繼續(xù)重寫URL為fe.lion.club/photos/1.jpg,找到/photos的location后,去html/photos目錄下尋找1.jpg靜態(tài)資源。
if 指令
語法:if?(condition)?{...}
上下文:server、location
示例:
if($http_user_agent?~?Chrome){
??rewrite?/(.*)/browser/$1?break;
}
復制代碼
condition 判斷條件:
$variable僅為變量時,值為空或以0開頭字符串都會被當做false處理;=或!=相等或不等;~正則匹配;! ~非正則匹配;~*正則匹配,不區(qū)分大小寫;-f或! -f檢測文件存在或不存在;-d或! -d檢測目錄存在或不存在;-e或! -e檢測文件、目錄、符號鏈接等存在或不存在;-x或! -x檢測文件可以執(zhí)行或不可執(zhí)行;
實例:
server?{
??listen?8080;
??server_name?localhost;
??root?html;
??
??location?/?{
???if?(?$uri?=?"/images/"?){
?????rewrite?(.*)?/pics/?break;
????}
??}
}
復制代碼
當訪問 localhost:8080/images/ 時,會進入 if 判斷里面執(zhí)行 rewrite 命令。
autoindex
用戶請求以 / 結尾時,列出目錄結構,可以用于快速搭建靜態(tài)資源下載網(wǎng)站。
autoindex.conf 配置信息:
server?{
??listen?80;
??server_name?fe.lion-test.club;
??
??location?/download/?{
????root?/opt/source;
????
????autoindex?on;?#?打開?autoindex,,可選參數(shù)有?on?|?off
????autoindex_exact_size?on;?#?修改為off,以KB、MB、GB顯示文件大小,默認為on,以bytes顯示出?件的確切??
????autoindex_format?html;?#?以html的方式進行格式化,可選參數(shù)有?html?|?json?|?xml
????autoindex_localtime?off;?#?顯示的?件時間為?件的服務器時間。默認為off,顯示的?件時間為GMT時間
??}
}
復制代碼
當訪問 fe.lion.com/download/ 時,會把服務器 /opt/source/download/ 路徑下的文件展示出來,如下圖所示:

變量
Nginx 提供給使用者的變量非常多,但是終究是一個完整的請求過程所產(chǎn)生數(shù)據(jù), Nginx 將這些數(shù)據(jù)以變量的形式提供給使用者。
下面列舉些項目中常用的變量:
| 變量名 | 含義 |
|---|---|
remote_addr | 客戶端 IP 地址 |
remote_port | 客戶端端口 |
server_addr | 服務端 IP 地址 |
server_port | 服務端端口 |
server_protocol | 服務端協(xié)議 |
binary_remote_addr | 二進制格式的客戶端 IP 地址 |
connection | TCP 連接的序號,遞增 |
connection_request | TCP 連接當前的請求數(shù)量 |
uri | 請求的URL,不包含參數(shù) |
request_uri | 請求的URL,包含參數(shù) |
scheme | 協(xié)議名, http 或 https |
request_method | 請求方法 |
request_length | 全部請求的長度,包含請求行、請求頭、請求體 |
args | 全部參數(shù)字符串 |
arg_參數(shù)名 | 獲取特定參數(shù)值 |
is_args | URL 中是否有參數(shù),有的話返回 ? ,否則返回空 |
query_string | 與 args 相同 |
host | 請求信息中的 Host ,如果請求中沒有 Host 行,則在請求頭中找,最后使用 nginx 中設置的 server_name 。 |
http_user_agent | 用戶瀏覽器 |
http_referer | 從哪些鏈接過來的請求 |
http_via | 每經(jīng)過一層代理服務器,都會添加相應的信息 |
http_cookie | 獲取用戶 cookie |
request_time | 處理請求已消耗的時間 |
https | 是否開啟了 https ,是則返回 on ,否則返回空 |
request_filename | 磁盤文件系統(tǒng)待訪問文件的完整路徑 |
document_root | 由 URI 和 root/alias 規(guī)則生成的文件夾路徑 |
limit_rate | 返回響應時的速度上限值 |
實例演示 var.conf :
server{
?listen?8081;
?server_name?var.lion-test.club;
?root?/usr/share/nginx/html;
?location?/?{
??return?200?"
remote_addr:?$remote_addr
remote_port:?$remote_port
server_addr:?$server_addr
server_port:?$server_port
server_protocol:?$server_protocol
binary_remote_addr:?$binary_remote_addr
connection:?$connection
uri:?$uri
request_uri:?$request_uri
scheme:?$scheme
request_method:?$request_method
request_length:?$request_length
args:?$args
arg_pid:?$arg_pid
is_args:?$is_args
query_string:?$query_string
host:?$host
http_user_agent:?$http_user_agent
http_referer:?$http_referer
http_via:?$http_via
request_time:?$request_time
https:?$https
request_filename:?$request_filename
document_root:?$document_root
";
?}
}
復制代碼
當我們訪問 http://var.lion-test.club:8081/test?pid=121414&cid=sadasd 時,由于 Nginx 中寫了 return 方法,因此 chrome 瀏覽器會默認為我們下載一個文件,下面展示的就是下載的文件內(nèi)容:
remote_addr:?27.16.220.84
remote_port:?56838
server_addr:?172.17.0.2
server_port:?8081
server_protocol:?HTTP/1.1
binary_remote_addr:?茉
connection:?126
uri:?/test/
request_uri:?/test/?pid=121414&cid=sadasd
scheme:?http
request_method:?GET
request_length:?518
args:?pid=121414&cid=sadasd
arg_pid:?121414
is_args:??
query_string:?pid=121414&cid=sadasd
host:?var.lion-test.club
http_user_agent:?Mozilla/5.0?(Macintosh;?Intel?Mac?OS?X?10_14_0)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/88.0.4324.182?Safari/537.36
http_referer:?
http_via:?
request_time:?0.000
https:?
request_filename:?/usr/share/nginx/html/test/
document_root:?/usr/share/nginx/html
復制代碼
Nginx 的配置還有非常多,以上只是羅列了一些常用的配置,在實際項目中還是要學會查閱文檔。
Nginx 應用核心概念
代理是在服務器和客戶端之間假設的一層服務器,代理將接收客戶端的請求并將它轉發(fā)給服務器,然后將服務端的響應轉發(fā)給客戶端。
不管是正向代理還是反向代理,實現(xiàn)的都是上面的功能。

正向代理
正向代理,意思是一個位于客戶端和原始服務器(origin server)之間的服務器,為了從原始服務器取得內(nèi)容,客戶端向代理發(fā)送一個請求并指定目標(原始服務器),然后代理向原始服務器轉交請求并將獲得的內(nèi)容返回給客戶端。
正向代理是為我們服務的,即為客戶端服務的,客戶端可以根據(jù)正向代理訪問到它本身無法訪問到的服務器資源。
正向代理對我們是透明的,對服務端是非透明的,即服務端并不知道自己收到的是來自代理的訪問還是來自真實客戶端的訪問。
反向代理
反向代理*(Reverse Proxy)方式是指以代理服務器來接受internet上的連接請求,然后將請求轉發(fā)給內(nèi)部網(wǎng)絡上的服務器,并將從服務器上得到的結果返回給internet上請求連接的客戶端,此時代理服務器對外就表現(xiàn)為一個反向代理服務器。
反向代理是為服務端服務的,反向代理可以幫助服務器接收來自客戶端的請求,幫助服務器做請求轉發(fā),負載均衡等。
反向代理對服務端是透明的,對我們是非透明的,即我們并不知道自己訪問的是代理服務器,而服務器知道反向代理在為他服務。
反向代理的優(yōu)勢:
隱藏真實服務器; 負載均衡便于橫向擴充后端動態(tài)服務; 動靜分離,提升系統(tǒng)健壯性;
那么“動靜分離”是什么?負載均衡又是什么?
動靜分離
動靜分離是指在 web 服務器架構中,將靜態(tài)頁面與動態(tài)頁面或者靜態(tài)內(nèi)容接口和動態(tài)內(nèi)容接口分開不同系統(tǒng)訪問的架構設計方法,進而提示整個服務的訪問性和可維護性。

一般來說,都需要將動態(tài)資源和靜態(tài)資源分開,由于 Nginx 的高并發(fā)和靜態(tài)資源緩存等特性,經(jīng)常將靜態(tài)資源部署在 Nginx 上。如果請求的是靜態(tài)資源,直接到靜態(tài)資源目錄獲取資源,如果是動態(tài)資源的請求,則利用反向代理的原理,把請求轉發(fā)給對應后臺應用去處理,從而實現(xiàn)動靜分離。
使用前后端分離后,可以很大程度提升靜態(tài)資源的訪問速度,即使動態(tài)服務不可用,靜態(tài)資源的訪問也不會受到影響。
負載均衡
一般情況下,客戶端發(fā)送多個請求到服務器,服務器處理請求,其中一部分可能要操作一些資源比如數(shù)據(jù)庫、靜態(tài)資源等,服務器處理完畢后,再將結果返回給客戶端。
這種模式對于早期的系統(tǒng)來說,功能要求不復雜,且并發(fā)請求相對較少的情況下還能勝任,成本也低。隨著信息數(shù)量不斷增長,訪問量和數(shù)據(jù)量飛速增長,以及系統(tǒng)業(yè)務復雜度持續(xù)增加,這種做法已無法滿足要求,并發(fā)量特別大時,服務器容易崩。
很明顯這是由于服務器性能的瓶頸造成的問題,除了堆機器之外,最重要的做法就是負載均衡。
請求爆發(fā)式增長的情況下,單個機器性能再強勁也無法滿足要求了,這個時候集群的概念產(chǎn)生了,單個服務器解決不了的問題,可以使用多個服務器,然后將請求分發(fā)到各個服務器上,將負載分發(fā)到不同的服務器,這就是負載均衡,核心是「分攤壓力」。Nginx 實現(xiàn)負載均衡,一般來說指的是將請求轉發(fā)給服務器集群。
舉個具體的例子,晚高峰乘坐地鐵的時候,入站口經(jīng)常會有地鐵工作人員大喇叭“請走 B 口, B 口人少車空....”,這個工作人員的作用就是負載均衡。
Nginx 實現(xiàn)負載均衡的策略:
輪詢策略:默認情況下采用的策略,將所有客戶端請求輪詢分配給服務端。這種策略是可以正常工作的,但是如果其中某一臺服務器壓力太大,出現(xiàn)延遲,會影響所有分配在這臺服務器下的用戶。 最小連接數(shù)策略:將請求優(yōu)先分配給壓力較小的服務器,它可以平衡每個隊列的長度,并避免向壓力大的服務器添加更多的請求。 最快響應時間策略:優(yōu)先分配給響應時間最短的服務器。 客戶端 ip綁定策略:來自同一個ip的請求永遠只分配一臺服務器,有效解決了動態(tài)網(wǎng)頁存在的session共享問題。
Nginx 實戰(zhàn)配置
在配置反向代理和負載均衡等等功能之前,有兩個核心模塊是我們必須要掌握的,這兩個模塊應該說是 Nginx 應用配置中的核心,它們分別是:upstream 、proxy_pass 。
upstream
用于定義上游服務器(指的就是后臺提供的應用服務器)的相關信息。

語法:upstream name {
?...
}
上下文:http
示例:
upstream?back_end_server{
??server?192.168.100.33:8081
}
復制代碼
在 upstream 內(nèi)可使用的指令:
server定義上游服務器地址;zone定義共享內(nèi)存,用于跨worker子進程;keepalive對上游服務啟用長連接;keepalive_requests一個長連接最多請求HTTP的個數(shù);keepalive_timeout空閑情形下,一個長連接的超時時長;hash哈希負載均衡算法;ip_hash依據(jù)IP進行哈希計算的負載均衡算法;least_conn最少連接數(shù)負載均衡算法;least_time最短響應時間負載均衡算法;random隨機負載均衡算法;
server
定義上游服務器地址。
語法:server address [parameters]
上下文:upstream
復制代碼
parameters 可選值:
weight=number權重值,默認為1;max_conns=number上游服務器的最大并發(fā)連接數(shù);fail_timeout=time服務器不可用的判定時間;max_fails=numer服務器不可用的檢查次數(shù);backup備份服務器,僅當其他服務器都不可用時才會啟用;down標記服務器長期不可用,離線維護;
keepalive
限制每個 worker 子進程與上游服務器空閑長連接的最大數(shù)量。
keepalive?connections;
上下文:upstream
示例:keepalive 16;
復制代碼
keepalive_requests
單個長連接可以處理的最多 HTTP 請求個數(shù)。
語法:keepalive_requests number;
默認值:keepalive_requests 100;
上下文:upstream
復制代碼
keepalive_timeout
空閑長連接的最長保持時間。
語法:keepalive_timeout time;
默認值:keepalive_timeout 60s;
上下文:upstream
復制代碼
配置實例
upstream?back_end{
?server?127.0.0.1:8081?weight=3?max_conns=1000?fail_timeout=10s?max_fails=2;
??keepalive?32;
??keepalive_requests?50;
??keepalive_timeout?30s;
}
復制代碼
proxy_pass
用于配置代理服務器。
語法:proxy_pass URL;
上下文:location、if、limit_except
示例:
proxy_pass?http://127.0.0.1:8081
proxy_pass?http://127.0.0.1:8081/proxy
復制代碼
URL 參數(shù)原則
URL必須以http或https開頭;URL中可以攜帶變量;URL中是否帶URI,會直接影響發(fā)往上游請求的URL;
接下來讓我們來看看兩種常見的 URL 用法:
proxy_pass http://192.168.100.33:8081proxy_pass http://192.168.100.33:8081/
這兩種用法的區(qū)別就是帶 / 和不帶 / ,在配置代理時它們的區(qū)別可大了:
不帶 /意味著Nginx不會修改用戶URL,而是直接透傳給上游的應用服務器;帶 /意味著Nginx會修改用戶URL,修改方法是將location后的URL從用戶URL中刪除;
不帶 / 的用法:
location?/bbs/{
??proxy_pass?http://127.0.0.1:8080;
}
復制代碼
分析:
用戶請求 URL:/bbs/abc/test.html請求到達 Nginx的URL:/bbs/abc/test.html請求到達上游應用服務器的 URL:/bbs/abc/test.html
帶 / 的用法:
location?/bbs/{
??proxy_pass?http://127.0.0.1:8080/;
}
復制代碼
分析:
用戶請求 URL:/bbs/abc/test.html請求到達 Nginx的URL:/bbs/abc/test.html請求到達上游應用服務器的 URL:/abc/test.html
并沒有拼接上 /bbs ,這點和 root 與 alias 之間的區(qū)別是保持一致的。
配置反向代理
這里為了演示更加接近實際,作者準備了兩臺云服務器,它們的公網(wǎng) IP 分別是:121.42.11.34 與 121.5.180.193 。
我們把 121.42.11.34 服務器作為上游服務器,做如下配置:
#?/etc/nginx/conf.d/proxy.conf
server{
??listen?8080;
??server_name?localhost;
??
??location?/proxy/?{
????root?/usr/share/nginx/html/proxy;
????index?index.html;
??}
}
#?/usr/share/nginx/html/proxy/index.html
?121.42.11.34?proxy?html?
復制代碼
配置完成后重啟 Nginx 服務器 nginx -s reload 。
把 121.5.180.193 服務器作為代理服務器,做如下配置:
#?/etc/nginx/conf.d/proxy.conf
upstream?back_end?{
??server?121.42.11.34:8080?weight=2?max_conns=1000?fail_timeout=10s?max_fails=3;
??keepalive?32;
??keepalive_requests?80;
??keepalive_timeout?20s;
}
server?{
??listen?80;
??server_name?proxy.lion.club;
??location?/proxy?{
???proxy_pass?http://back_end/proxy;
??}
}
復制代碼
本地機器要訪問 proxy.lion.club 域名,因此需要配置本地 hosts ,通過命令:vim /etc/hosts 進入配置文件,添加如下內(nèi)容:
121.5.180.193?proxy.lion.club
復制代碼

分析:
當訪問 proxy.lion.club/proxy時通過upstream的配置找到121.42.11.34:8080;因此訪問地址變?yōu)? http://121.42.11.34:8080/proxy;連接到 121.42.11.34服務器,找到8080端口提供的server;通過 server找到/usr/share/nginx/html/proxy/index.html資源,最終展示出來。
配置負載均衡
配置負載均衡主要是要使用 upstream 指令。
我們把 121.42.11.34 服務器作為上游服務器,做如下配置( /etc/nginx/conf.d/balance.conf ):
server{
??listen?8020;
??location?/?{
???return?200?'return?8020?\n';
??}
}
server{
??listen?8030;
??location?/?{
???return?200?'return?8030?\n';
??}
}
server{
??listen?8040;
??location?/?{
???return?200?'return?8040?\n';
??}
}
復制代碼
配置完成后:
nginx -t檢測配置是否正確;nginx -s reload重啟Nginx服務器;執(zhí)行 ss -nlt命令查看端口是否被占用,從而判斷Nginx服務是否正確啟動。
把 121.5.180.193 服務器作為代理服務器,做如下配置( /etc/nginx/conf.d/balance.conf ):
upstream?demo_server?{
??server?121.42.11.34:8020;
??server?121.42.11.34:8030;
??server?121.42.11.34:8040;
}
server?{
??listen?80;
??server_name?balance.lion.club;
??
??location?/balance/?{
???proxy_pass?http://demo_server;
??}
}
復制代碼
配置完成后重啟 Nginx 服務器。并且在需要訪問的客戶端配置好 ip 和域名的映射關系。
#?/etc/hosts
121.5.180.193?balance.lion.club
復制代碼
在客戶端機器執(zhí)行 curl http://balance.lion.club/balance/ 命令:

不難看出,負載均衡的配置已經(jīng)生效了,每次給我們分發(fā)的上游服務器都不一樣。就是通過簡單的輪詢策略進行上游服務器分發(fā)。
接下來,我們再來了解下 Nginx 的其它分發(fā)策略。
hash 算法
通過制定關鍵字作為 hash key ,基于 hash 算法映射到特定的上游服務器中。關鍵字可以包含有變量、字符串。
upstream?demo_server?{
??hash?$request_uri;
??server?121.42.11.34:8020;
??server?121.42.11.34:8030;
??server?121.42.11.34:8040;
}
server?{
??listen?80;
??server_name?balance.lion.club;
??
??location?/balance/?{
???proxy_pass?http://demo_server;
??}
}
復制代碼
hash $request_uri 表示使用 request_uri 變量作為 hash 的 key 值,只要訪問的 URI 保持不變,就會一直分發(fā)給同一臺服務器。
ip_hash
根據(jù)客戶端的請求 ip 進行判斷,只要 ip 地址不變就永遠分配到同一臺主機。它可以有效解決后臺服務器 session 保持的問題。
upstream?demo_server?{
??ip_hash;
??server?121.42.11.34:8020;
??server?121.42.11.34:8030;
??server?121.42.11.34:8040;
}
server?{
??listen?80;
??server_name?balance.lion.club;
??
??location?/balance/?{
???proxy_pass?http://demo_server;
??}
}
復制代碼
最少連接數(shù)算法
各個 worker 子進程通過讀取共享內(nèi)存的數(shù)據(jù),來獲取后端服務器的信息。來挑選一臺當前已建立連接數(shù)最少的服務器進行分配請求。
語法:least_conn;
上下文:upstream;
復制代碼
示例:
upstream?demo_server?{
??zone?test?10M;?#?zone可以設置共享內(nèi)存空間的名字和大小
??least_conn;
??server?121.42.11.34:8020;
??server?121.42.11.34:8030;
??server?121.42.11.34:8040;
}
server?{
??listen?80;
??server_name?balance.lion.club;
??
??location?/balance/?{
???proxy_pass?http://demo_server;
??}
}
復制代碼
最后你會發(fā)現(xiàn),負載均衡的配置其實一點都不復雜。
配置緩存
緩存可以非常有效的提升性能,因此不論是客戶端(瀏覽器),還是代理服務器( Nginx ),乃至上游服務器都多少會涉及到緩存。可見緩存在每個環(huán)節(jié)都是非常重要的。下面讓我們來學習 Nginx 中如何設置緩存策略。
proxy_cache
存儲一些之前被訪問過、而且可能將要被再次訪問的資源,使用戶可以直接從代理服務器獲得,從而減少上游服務器的壓力,加快整個訪問速度。
語法:proxy_cache zone | off ;?#?zone?是共享內(nèi)存的名稱
默認值:proxy_cache off;
上下文:http、server、location
復制代碼
proxy_cache_path
設置緩存文件的存放路徑。
語法:proxy_cache_path path [level=levels] ...可選參數(shù)省略,下面會詳細列舉
默認值:proxy_cache_path off
上下文:http
復制代碼
參數(shù)含義:
path緩存文件的存放路徑;level path的目錄層級;keys_zone設置共享內(nèi)存;inactive在指定時間內(nèi)沒有被訪問,緩存會被清理,默認10分鐘;
proxy_cache_key
設置緩存文件的 key 。
語法:proxy_cache_key
默認值:proxy_cache_key $scheme$proxy_host$request_uri;
上下文:http、server、location
復制代碼
proxy_cache_valid
配置什么狀態(tài)碼可以被緩存,以及緩存時長。
語法:proxy_cache_valid [code...] time;
上下文:http、server、location
配置示例:proxy_cache_valid 200 304 2m;;?#?說明對于狀態(tài)為200和304的緩存文件的緩存時間是2分鐘
復制代碼
proxy_no_cache
定義相應保存到緩存的條件,如果字符串參數(shù)的至少一個值不為空且不等于“ 0”,則將不保存該響應到緩存。
語法:proxy_no_cache string;
上下文:http、server、location
示例:proxy_no_cache $http_pragma????$http_authorization;
復制代碼
proxy_cache_bypass
定義條件,在該條件下將不會從緩存中獲取響應。
語法:proxy_cache_bypass string;
上下文:http、server、location
示例:proxy_cache_bypass $http_pragma????$http_authorization;
復制代碼
upstream_cache_status 變量
它存儲了緩存是否命中的信息,會設置在響應頭信息中,在調(diào)試中非常有用。
MISS:?未命中緩存
HIT:?命中緩存
EXPIRED:?緩存過期
STALE:?命中了陳舊緩存
REVALIDDATED:?Nginx驗證陳舊緩存依然有效
UPDATING:?內(nèi)容陳舊,但正在更新
BYPASS:?X響應從原始服務器獲取
復制代碼
配置實例
我們把 121.42.11.34 服務器作為上游服務器,做如下配置( /etc/nginx/conf.d/cache.conf ):
server?{
??listen?1010;
??root?/usr/share/nginx/html/1010;
??location?/?{
???index?index.html;
??}
}
server?{
??listen?1020;
??root?/usr/share/nginx/html/1020;
??location?/?{
???index?index.html;
??}
}
復制代碼
把 121.5.180.193 服務器作為代理服務器,做如下配置( /etc/nginx/conf.d/cache.conf ):
proxy_cache_path?/etc/nginx/cache_temp?levels=2:2?keys_zone=cache_zone:30m?max_size=2g?inactive=60m?use_temp_path=off;
upstream?cache_server{
??server?121.42.11.34:1010;
??server?121.42.11.34:1020;
}
server?{
??listen?80;
??server_name?cache.lion.club;
??location?/?{
????proxy_cache?cache_zone;?#?設置緩存內(nèi)存,上面配置中已經(jīng)定義好的
????proxy_cache_valid?200?5m;?#?緩存狀態(tài)為200的請求,緩存時長為5分鐘
????proxy_cache_key?$request_uri;?#?緩存文件的key為請求的URI
????add_header?Nginx-Cache-Status?$upstream_cache_status?#?把緩存狀態(tài)設置為頭部信息,響應給客戶端
????proxy_pass?http://cache_server;?#?代理轉發(fā)
??}
}
復制代碼
緩存就是這樣配置,我們可以在 /etc/nginx/cache_temp 路徑下找到相應的緩存文件。
對于一些實時性要求非常高的頁面或數(shù)據(jù)來說,就不應該去設置緩存,下面來看看如何配置不緩存的內(nèi)容。
...
server?{
??listen?80;
??server_name?cache.lion.club;
??#?URI?中后綴為?.txt?或?.text?的設置變量值為?"no?cache"
??if?($request_uri?~?\.(txt|text)$)?{
???set?$cache_name?"no?cache"
??}
??
??location?/?{
????proxy_no_cache?$cache_name;?#?判斷該變量是否有值,如果有值則不進行緩存,如果沒有值則進行緩存
????proxy_cache?cache_zone;?#?設置緩存內(nèi)存
????proxy_cache_valid?200?5m;?#?緩存狀態(tài)為200的請求,緩存時長為5分鐘
????proxy_cache_key?$request_uri;?#?緩存文件的key為請求的URI
????add_header?Nginx-Cache-Status?$upstream_cache_status?#?把緩存狀態(tài)設置為頭部信息,響應給客戶端
????proxy_pass?http://cache_server;?#?代理轉發(fā)
??}
}
復制代碼
HTTPS
在學習如何配置 HTTPS 之前,我們先來簡單回顧下 HTTPS 的工作流程是怎么樣的?它是如何進行加密保證安全的?
HTTPS 工作流程
客戶端(瀏覽器)訪問 https://www.baidu.com百度網(wǎng)站;百度服務器返回 HTTPS使用的CA證書;瀏覽器驗證 CA證書是否為合法證書;驗證通過,證書合法,生成一串隨機數(shù)并使用公鑰(證書中提供的)進行加密; 發(fā)送公鑰加密后的隨機數(shù)給百度服務器; 百度服務器拿到密文,通過私鑰進行解密,獲取到隨機數(shù)(公鑰加密,私鑰解密,反之也可以); 百度服務器把要發(fā)送給瀏覽器的內(nèi)容,使用隨機數(shù)進行加密后傳輸給瀏覽器; 此時瀏覽器可以使用隨機數(shù)進行解密,獲取到服務器的真實傳輸內(nèi)容;
這就是 HTTPS 的基本運作原理,使用對稱加密和非對稱機密配合使用,保證傳輸內(nèi)容的安全性。
關于HTTPS更多知識,可以查看作者的另外一篇文章《學習 HTTP 協(xié)議》。
配置證書
下載證書的壓縮文件,里面有個 Nginx 文件夾,把 xxx.crt 和 xxx.key 文件拷貝到服務器目錄,再進行如下配置:
server?{
??listen?443?ssl?http2?default_server;???#?SSL?訪問端口號為?443
??server_name?lion.club;?????????#?填寫綁定證書的域名(我這里是隨便寫的)
??ssl_certificate?/etc/nginx/https/lion.club_bundle.crt;???#?證書地址
??ssl_certificate_key?/etc/nginx/https/lion.club.key;??????#?私鑰地址
??ssl_session_timeout?10m;
??ssl_protocols?TLSv1?TLSv1.1?TLSv1.2;?#?支持ssl協(xié)議版本,默認為后三個,主流版本是[TLSv1.2]
?
??location?/?{
????root?????????/usr/share/nginx/html;
????index????????index.html?index.htm;
??}
}
復制代碼
如此配置后就能正常訪問 HTTPS 版的網(wǎng)站了。
配置跨域 CORS
先簡單回顧下跨域究竟是怎么回事。
跨域的定義
同源策略限制了從同一個源加載的文檔或腳本如何與來自另一個源的資源進行交互。這是一個用于隔離潛在惡意文件的重要安全機制。通常不允許不同源間的讀操作。
同源的定義
如果兩個頁面的協(xié)議,端口(如果有指定)和域名都相同,則兩個頁面具有相同的源。
下面給出了與 URL http://store.company.com/dir/page.html 的源進行對比的示例:
http://store.company.com/dir2/other.html?同源
https://store.company.com/secure.html?不同源,協(xié)議不同
http://store.company.com:81/dir/etc.html?不同源,端口不同
http://news.company.com/dir/other.html?不同源,主機不同
復制代碼
不同源會有如下限制:
Web數(shù)據(jù)層面,同源策略限制了不同源的站點讀取當前站點的Cookie、IndexDB、LocalStorage等數(shù)據(jù)。DOM層面,同源策略限制了來自不同源的JavaScript腳本對當前DOM對象讀和寫的操作。網(wǎng)絡層面,同源策略限制了通過 XMLHttpRequest等方式將站點的數(shù)據(jù)發(fā)送給不同源的站點。
Nginx 解決跨域的原理
例如:
前端 server的域名為:fe.server.com后端服務的域名為: dev.server.com
現(xiàn)在我在 fe.server.com 對 dev.server.com 發(fā)起請求一定會出現(xiàn)跨域。
現(xiàn)在我們只需要啟動一個 Nginx 服務器,將 server_name 設置為 fe.server.com 然后設置相應的 location 以攔截前端需要跨域的請求,最后將請求代理回 dev.server.com 。如下面的配置:
server?{
?listen??????80;
?server_name??fe.server.com;
?location?/?{
??proxy_pass?dev.server.com;
?}
}
復制代碼
這樣可以完美繞過瀏覽器的同源策略:fe.server.com 訪問 Nginx 的 fe.server.com 屬于同源訪問,而 Nginx 對服務端轉發(fā)的請求不會觸發(fā)瀏覽器的同源策略。
配置開啟 gzip 壓縮
GZIP 是規(guī)定的三種標準 HTTP 壓縮格式之一。目前絕大多數(shù)的網(wǎng)站都在使用 GZIP 傳輸 HTML 、CSS 、 JavaScript 等資源文件。
對于文本文件, GZiP 的效果非常明顯,開啟后傳輸所需流量大約會降至 1/4~1/3 。
并不是每個瀏覽器都支持 gzip 的,如何知道客戶端是否支持 gzip 呢,請求頭中的 Accept-Encoding 來標識對壓縮的支持。
啟用 gzip 同時需要客戶端和服務端的支持,如果客戶端支持 gzip 的解析,那么只要服務端能夠返回 gzip 的文件就可以啟用 gzip 了,我們可以通過 Nginx 的配置來讓服務端支持 gzip 。下面的 respone 中 content-encoding:gzip ,指服務端開啟了 gzip 的壓縮方式。
在 /etc/nginx/conf.d/ 文件夾中新建配置文件 gzip.conf :
#?#?默認off,是否開啟gzip
gzip?on;?
#?要采用 gzip 壓縮的 MIME 文件類型,其中 text/html 被系統(tǒng)強制啟用;
gzip_types?text/plain?text/css?application/json?application/x-javascript?text/xml?application/xml?application/xml+rss?text/javascript;
#?----?以上兩個參數(shù)開啟就可以支持Gzip壓縮了?----?#
#?默認 off,該模塊啟用后,Nginx 首先檢查是否存在請求靜態(tài)文件的 gz 結尾的文件,如果有則直接返回該 .gz 文件內(nèi)容;
gzip_static?on;
#?默認 off,nginx做為反向代理時啟用,用于設置啟用或禁用從代理服務器上收到相應內(nèi)容 gzip 壓縮;
gzip_proxied?any;
#?用于在響應消息頭中添加 Vary:Accept-Encoding,使代理服務器根據(jù)請求頭中的 Accept-Encoding 識別是否啟用 gzip 壓縮;
gzip_vary?on;
# gzip 壓縮比,壓縮級別是 1-9,1 壓縮級別最低,9 最高,級別越高壓縮率越大,壓縮時間越長,建議 4-6;
gzip_comp_level?6;
#?獲取多少內(nèi)存用于緩存壓縮結果,16 8k 表示以 8k*16 為單位獲得;
gzip_buffers?16?8k;
#?允許壓縮的頁面最小字節(jié)數(shù),頁面字節(jié)數(shù)從header頭中的 Content-Length 中進行獲取。默認值是?0,不管頁面多大都壓縮。建議設置成大于 1k 的字節(jié)數(shù),小于 1k 可能會越壓越大;
#?gzip_min_length?1k;
#?默認 1.1,啟用 gzip 所需的 HTTP 最低版本;
gzip_http_version?1.1;
復制代碼
其實也可以通過前端構建工具例如 webpack 、rollup 等在打生產(chǎn)包時就做好 Gzip 壓縮,然后放到 Nginx 服務器中,這樣可以減少服務器的開銷,加快訪問速度。
關于 Nginx 的實際應用就學習到這里,相信通過掌握了 Nginx 核心配置以及實戰(zhàn)配置,之后再遇到什么需求,我們也能輕松應對。接下來,讓我們再深入一點學習下 Nginx 的架構。
Nginx 架構
進程結構
多進程結構 Nginx 的進程模型圖:

多進程中的 Nginx 進程架構如下圖所示,會有一個父進程( Master Process ),它會有很多子進程( Child Processes )。
Master?Process用來管理子進程的,其本身并不真正處理用戶請求。
某個子進程 down掉的話,它會向Master進程發(fā)送一條消息,表明自己不可用了,此時Master進程會去新起一個子進程。某個配置文件被修改了 Master進程會去通知work進程獲取新的配置信息,這也就是我們所說的熱部署。子進程間是通過共享內(nèi)存的方式進行通信的。
配置文件重載原理
reload 重載配置文件的流程:
向 master進程發(fā)送HUP信號(reload命令);master進程檢查配置語法是否正確;master進程打開監(jiān)聽端口;master進程使用新的配置文件啟動新的worker子進程;master進程向老的worker子進程發(fā)送QUIT信號;老的 worker進程關閉監(jiān)聽句柄,處理完當前連接后關閉進程;整個過程 Nginx始終處于平穩(wěn)運行中,實現(xiàn)了平滑升級,用戶無感知;
Nginx 模塊化管理機制
Nginx 的內(nèi)部結構是由核心部分和一系列的功能模塊所組成。這樣劃分是為了使得每個模塊的功能相對簡單,便于開發(fā),同時也便于對系統(tǒng)進行功能擴展。Nginx 的模塊是互相獨立的,低耦合高內(nèi)聚。
總結
相信通過本文的學習,你應該會對 Nginx 有一個更加全面的認識。
