這篇文章帶你全面掌握 Nginx !
原文鏈接:juejin.cn/post/6942607113118023710
前言
作為一名開發(fā)人員,你是不是經(jīng)常碰到領(lǐng)導(dǎo)讓你上服務(wù)器去修改 Nginx 配置,然而你可能會對這些配置并不熟悉!今天就讓我們一起告別這種尷尬,向“真正”的程序員邁進(jìn)。
1. Nginx 概述
Nginx?是開源、高性能、高可靠的 Web 和反向代理服務(wù)器,而且支持熱部署,幾乎可以做到 7 * 24 小時不間斷運(yùn)行,即使運(yùn)行幾個月也不需要重新啟動,還能在不間斷服務(wù)的情況下對軟件版本進(jìn)行熱更新。性能是 Nginx 最重要的考量,其占用內(nèi)存少、并發(fā)能力強(qiáng)、能支持高達(dá) 5w 個并發(fā)連接數(shù),最重要的是, Nginx 是免費的并可以商業(yè)化,配置使用也比較簡單。
2. Nginx 特點
高并發(fā)、高性能; 模塊化架構(gòu)使得它的擴(kuò)展性非常好; 異步非阻塞的事件驅(qū)動模型這點和 Node.js 相似; 相對于其它服務(wù)器來說它可以連續(xù)幾個月甚至更長而不需要重啟服務(wù)器使得它具有高可靠性; 熱部署、平滑升級; 完全開源,生態(tài)繁榮。
3. Nginx 作用
Nginx 的最重要的幾個使用場景:
靜態(tài)資源服務(wù),通過本地文件系統(tǒng)提供服務(wù); 反向代理服務(wù),延伸出包括緩存、負(fù)載均衡等; API 服務(wù), OpenResty。
對于前端來說 Node.js 并不陌生, Nginx 和 Node.js 的很多理念類似, HTTP 服務(wù)器、事件驅(qū)動、異步非阻塞等,且 Nginx 的大部分功能使用 Node.js 也可以實現(xiàn),但 Nginx 和 Node.js 并不沖突,都有自己擅長的領(lǐng)域。Nginx 擅長于底層服務(wù)器端資源的處理(靜態(tài)資源處理轉(zhuǎn)發(fā)、反向代理,負(fù)載均衡等), Node.js 更擅長上層具體業(yè)務(wù)邏輯的處理,兩者可以完美組合。
用一張圖表示:

4. Nginx 安裝
本文演示的是 Linux centOS 7.x 的操作系統(tǒng)上安裝 Nginx ,至于在其它操作系統(tǒng)上進(jìn)行安裝可以網(wǎng)上自行搜索,都非常簡單的。
使用 ?yum 安裝 Nginx :
yum install nginx -y安裝完成后,通過 rpm -ql nginx 命令查看 Nginx 的安裝信息:
/etc/nginx/nginx.conf/etc/nginx/nginx.conf.default/usr/bin/nginx-upgrade/usr/sbin/nginx/usr/lib/systemd/system/nginx.service/usr/lib64/nginx/modules/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/usr/share/nginx/html/404.html/usr/share/nginx/html/50x.html/usr/share/nginx/html/index.html/var/log/nginx
主要關(guān)注的文件夾有兩個:
/etc/nginx/conf.d/?是子配置項存放處,?/etc/nginx/nginx.conf 主配置文件會默認(rèn)把這個文件夾中所有子配置項都引入; /usr/share/nginx/html/?靜態(tài)文件都放在這個文件夾,也可以根據(jù)你自己的習(xí)慣放在其他地方。
5. Nginx 常用命令
systemctl 系統(tǒng)命令:
# 開機(jī)配置systemctl enable nginx # 開機(jī)自動啟動systemctl disable nginx # 關(guān)閉開機(jī)自動啟動# 啟動Nginxsystemctl start nginx # 啟動Nginx成功后,可以直接訪問主機(jī)IP,此時會展示Nginx默認(rèn)頁面# 停止Nginxsystemctl stop nginx# 重啟Nginxsystemctl restart nginx# 重新加載Nginxsystemctl reload nginx# 查看 Nginx 運(yùn)行狀態(tài)systemctl status nginx# 查看Nginx進(jìn)程ps -ef | grep nginx# 殺死Nginx進(jìn)程kill -9 pid # 根據(jù)上面查看到的Nginx進(jìn)程號,殺死Nginx進(jìn)程,-9 表示強(qiáng)制結(jié)束進(jìn)程
Nginx 應(yīng)用程序命令:
nginx -s reload # 向主進(jìn)程發(fā)送信號,重新加載配置文件,熱重啟nginx -s reopen # 重啟 Nginxnginx -s stop # 快速關(guān)閉nginx -s quit # 等待工作進(jìn)程處理完成后關(guān)閉nginx -T # 查看當(dāng)前 Nginx 最終的配置nginx?-t?????????#?檢查配置是否有問
6. Nginx 核心配置
6.1 配置文件結(jié)構(gòu)
Nginx 的典型配置示例:
# main段配置信息user nginx; # 運(yùn)行用戶,默認(rèn)即是nginx,可以不進(jìn)行設(shè)置worker_processes auto; # Nginx 進(jìn)程數(shù),一般設(shè)置為和 CPU 核數(shù)一樣error_log /var/log/nginx/error.log warn; # Nginx 的錯誤日志存放目錄pid /var/run/nginx.pid; # Nginx 服務(wù)啟動時的 pid 存放位置# events段配置信息events {use epoll; # 使用epoll的I/O模型(如果你不知道Nginx該使用哪種輪詢方法,會自動選擇一個最適合你操作系統(tǒng)的)worker_connections 1024; # 每個進(jìn)程允許最大并發(fā)數(shù)}# http段配置信息# 配置使用最頻繁的部分,代理、緩存、日志定義等絕大多數(shù)功能和第三方模塊的配置都在這里設(shè)置http {# 設(shè)置日志模式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)絡(luò)報文段的數(shù)量tcp_nodelay on;keepalive_timeout 65; # 保持連接的時間,也叫超時時間,單位秒types_hash_max_size 2048;include /etc/nginx/mime.types; # 文件擴(kuò)展名與類型映射表default_type application/octet-stream; # 默認(rèn)文件類型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; # 默認(rèn)首頁文件deny 172.168.22.11; # 禁止訪問的ip地址,可以為allallow 172.168.33.44;# 允許訪問的ip地址,可以為all}error_page 500 502 503 504 /50x.html; # 默認(rèn)50x對應(yīng)的訪問頁面error_page 400 404 error.html; # 同上}}
main:全局配置,對全局生效; events:配置影響 Nginx 服務(wù)器與用戶的網(wǎng)絡(luò)連接; http:配置代理,緩存,日志定義等絕大多數(shù)功能和第三方模塊的配置; server:配置虛擬主機(jī)的相關(guān)參數(shù),一個 http 塊中可以有多個 server 塊; location:用于配置匹配的 uri ; upstream:配置后端服務(wù)器具體地址,負(fù)載均衡配置不可或缺的部分。
用一張圖清晰的展示它的層級結(jié)構(gòu):
Docker+K8s+Jenkins 主流技術(shù)全解視頻資料

6.2 配置文件 main 段核心參數(shù)
user:指定運(yùn)行?Nginx 的 woker 子進(jìn)程的屬主和屬組,其中組可以不指定。
user?USERNAME?[GROUP]user nginx lion; # 用戶是nginx;組是lion
pid:指定運(yùn)行 Nginx master 主進(jìn)程的 pid 文件存放路徑。
pid /opt/nginx/logs/nginx.pid # master主進(jìn)程的的pid存放在nginx.pid的文件worker_rlimit_nofile_number:指定?worker 子進(jìn)程可以打開的最大文件句柄數(shù)。
worker_rlimit_nofile 20480; # 可以理解成每個worker子進(jìn)程的最大連接數(shù)量。worker_rlimit_core:指定 worker 子進(jìn)程異常終止后的 core 文件,用于記錄分析問題。
worker_rlimit_core 50M; # 存放大小限制working_directory /opt/nginx/tmp; # 存放目錄
worker_processes_number:指定 Nginx 啟動的 worker 子進(jìn)程數(shù)量。
worker_processes 4; # 指定具體子進(jìn)程數(shù)量worker_processes auto; # 與當(dāng)前cpu物理核心數(shù)一致
worker_cpu_affinity:將每個 worker 子進(jìn)程與我們的 cpu 物理核心綁定。

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

6.4 變量
Nginx 提供給使用者的變量非常多,但是終究是一個完整的請求過程所產(chǎn)生數(shù)據(jù), Nginx 將這些數(shù)據(jù)以變量的形式提供給使用者。
下面列舉些項目中常用的變量:

實例演示 var.conf :
server{listen 8081;server_name var.lion-test.club;root /usr/share/nginx/html;location / {return 200 "remote_addr: $remote_addrremote_port: $remote_portserver_addr: $server_addrserver_port: $server_portserver_protocol: $server_protocolbinary_remote_addr: $binary_remote_addrconnection: $connectionuri: $urirequest_uri: $request_urischeme: $schemerequest_method: $request_methodrequest_length: $request_lengthargs: $argsarg_pid: $arg_pidis_args: $is_argsquery_string: $query_stringhost: $hosthttp_user_agent: $http_user_agenthttp_referer: $http_refererhttp_via: $http_viarequest_time: $request_timehttps: $httpsrequest_filename: $request_filenamedocument_root: $document_root";}}
Docker+K8s+Jenkins 主流技術(shù)全解視頻資料
當(dāng)我們訪問 http://var.lion-test.club:8081/test?pid=121414&cid=sadasd 時,由于 Nginx 中寫了 return 方法,因此 chrome 瀏覽器會默認(rèn)為我們下載一個文件,下面展示的就是下載的文件內(nèi)容:
remote_addr: 27.16.220.84remote_port: 56838server_addr: 172.17.0.2server_port: 8081server_protocol: HTTP/1.1binary_remote_addr: 茉connection: 126uri: /test/request_uri: /test/?pid=121414&cid=sadasdscheme: httprequest_method: GETrequest_length: 518args: pid=121414&cid=sadasdarg_pid: 121414is_args: ?query_string: pid=121414&cid=sadasdhost: var.lion-test.clubhttp_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.36http_referer:http_via:request_time: 0.000https:request_filename: /usr/share/nginx/html/test/document_root: /usr/share/nginx/html
Nginx 的配置還有非常多,以上只是羅列了一些常用的配置,在實際項目中還是要學(xué)會查閱文檔。
7.?Nginx 應(yīng)用核心概念
代理是在服務(wù)器和客戶端之間假設(shè)的一層服務(wù)器,代理將接收客戶端的請求并將它轉(zhuǎn)發(fā)給服務(wù)器,然后將服務(wù)端的響應(yīng)轉(zhuǎn)發(fā)給客戶端。
不管是正向代理還是反向代理,實現(xiàn)的都是上面的功能。

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

一般來說,都需要將動態(tài)資源和靜態(tài)資源分開,由于 Nginx 的高并發(fā)和靜態(tài)資源緩存等特性,經(jīng)常將靜態(tài)資源部署在 Nginx 上。如果請求的是靜態(tài)資源,直接到靜態(tài)資源目錄獲取資源,如果是動態(tài)資源的請求,則利用反向代理的原理,把請求轉(zhuǎn)發(fā)給對應(yīng)后臺應(yīng)用去處理,從而實現(xiàn)動靜分離。
使用前后端分離后,可以很大程度提升靜態(tài)資源的訪問速度,即使動態(tài)服務(wù)不可用,靜態(tài)資源的訪問也不會受到影響。
7.4 負(fù)載均衡
一般情況下,客戶端發(fā)送多個請求到服務(wù)器,服務(wù)器處理請求,其中一部分可能要操作一些資源比如數(shù)據(jù)庫、靜態(tài)資源等,服務(wù)器處理完畢后,再將結(jié)果返回給客戶端。
這種模式對于早期的系統(tǒng)來說,功能要求不復(fù)雜,且并發(fā)請求相對較少的情況下還能勝任,成本也低。隨著信息數(shù)量不斷增長,訪問量和數(shù)據(jù)量飛速增長,以及系統(tǒng)業(yè)務(wù)復(fù)雜度持續(xù)增加,這種做法已無法滿足要求,并發(fā)量特別大時,服務(wù)器容易崩。
很明顯這是由于服務(wù)器性能的瓶頸造成的問題,除了堆機(jī)器之外,最重要的做法就是負(fù)載均衡。
請求爆發(fā)式增長的情況下,單個機(jī)器性能再強(qiáng)勁也無法滿足要求了,這個時候集群的概念產(chǎn)生了,單個服務(wù)器解決不了的問題,可以使用多個服務(wù)器,然后將請求分發(fā)到各個服務(wù)器上,將負(fù)載分發(fā)到不同的服務(wù)器,這就是負(fù)載均衡,核心是「分?jǐn)倝毫Α埂ginx 實現(xiàn)負(fù)載均衡,一般來說指的是將請求轉(zhuǎn)發(fā)給服務(wù)器集群。
舉個具體的例子,晚高峰乘坐地鐵的時候,入站口經(jīng)常會有地鐵工作人員大喇叭“請走 B 口, B 口人少車空....”,這個工作人員的作用就是負(fù)載均衡。

Nginx 實現(xiàn)負(fù)載均衡的策略:
輪詢策略:默認(rèn)情況下采用的策略,將所有客戶端請求輪詢分配給服務(wù)端。這種策略是可以正常工作的,但是如果其中某一臺服務(wù)器壓力太大,出現(xiàn)延遲,會影響所有分配在這臺服務(wù)器下的用戶; 最小連接數(shù)策略:將請求優(yōu)先分配給壓力較小的服務(wù)器,它可以平衡每個隊列的長度,并避免向壓力大的服務(wù)器添加更多的請求; 最快響應(yīng)時間策略:優(yōu)先分配給響應(yīng)時間最短的服務(wù)器; 客戶端 IP?綁定策略:來自同一個 IP 的請求永遠(yuǎn)只分配一臺服務(wù)器,有效解決了動態(tài)網(wǎng)頁存在的 session 共享問題。
8. Nginx 實戰(zhàn)配置
在配置反向代理和負(fù)載均衡等等功能之前,有兩個核心模塊是我們必須要掌握的,這兩個模塊應(yīng)該說是 Nginx 應(yīng)用配置中的核心,它們分別是:upstream 、proxy_pass 。
8.1 upstream
用于定義上游服務(wù)器(指的就是后臺提供的應(yīng)用服務(wù)器)的相關(guān)信息。

name {...}上下文:http示例:upstream back_end_server{server 192.168.100.33:8081}
server 定義上游服務(wù)器地址; zone 定義共享內(nèi)存,用于跨 worker 子進(jìn)程; keepalive 對上游服務(wù)啟用長連接; keepalive_requests 一個長連接最多請求 HTTP 的個數(shù); keepalive_timeout 空閑情形下,一個長連接的超時時長; hash 哈希負(fù)載均衡算法; ip_hash 依據(jù) IP 進(jìn)行哈希計算的負(fù)載均衡算法; least_conn 最少連接數(shù)負(fù)載均衡算法; least_time 最短響應(yīng)時間負(fù)載均衡算法; random 隨機(jī)負(fù)載均衡算法。
server
定義上游服務(wù)器地址。
語法:server address [parameters]上下文:upstream
parameters?可選值:
weight=number 權(quán)重值,默認(rèn)為1; max_conns=number 上游服務(wù)器的最大并發(fā)連接數(shù); fail_timeout=time 服務(wù)器不可用的判定時間; max_fails=numer 服務(wù)器不可用的檢查次數(shù); backup 備份服務(wù)器,僅當(dāng)其他服務(wù)器都不可用時才會啟用; down 標(biāo)記服務(wù)器長期不可用,離線維護(hù)。
keepalive
限制每個 worker 子進(jìn)程與上游服務(wù)器空閑長連接的最大數(shù)量。
keepalive connections;上下文:upstream示例:keepalive 16;
keepalive_requests
單個長連接可以處理的最多 HTTP 請求個數(shù)。
語法:keepalive_requests number;默認(rèn)值:keepalive_requests 100;上下文:upstream
keepalive_timeout
空閑長連接的最長保持時間。
語法:keepalive_timeout time;默認(rèn)值:keepalive_timeout 60s;上下文:upstream
配置實例
語法:keepalive_timeout time;默認(rèn)值:keepalive_timeout 60s;上下文:upstream
8.2 proxy_pass
用于配置代理服務(wù)器。
語法:proxy_pass URL;上下文:location、if、limit_except示例:proxy_pass http://127.0.0.1:8081proxy_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:8081 proxy_pass http://192.168.100.33:8081/
這兩種用法的區(qū)別就是帶?/?和不帶?/?,在配置代理時它們的區(qū)別可大了:
不帶?/?意味著 Nginx 不會修改用戶 URL ,而是直接透傳給上游的應(yīng)用服務(wù)器; 帶?/?意味著 Nginx 會修改用戶 URL ,修改方法是將 location 后的 URL 從用戶 URL 中刪除。
不帶?/?的用法:
location /bbs/{proxy_pass http://127.0.0.1:8080;}
分析:
用戶請求 URL :/bbs/abc/test.html 請求到達(dá) Nginx 的 URL :/bbs/abc/test.html 請求到達(dá)上游應(yīng)用服務(wù)器的 URL :/bbs/abc/test.html
帶?/?的用法:
location /bbs/{proxy_pass http://127.0.0.1:8080/;}
分析:
用戶請求 URL :/bbs/abc/test.html 請求到達(dá) Nginx 的 URL :/bbs/abc/test.html 請求到達(dá)上游應(yīng)用服務(wù)器的 URL :/abc/test.html
并沒有拼接上?/bbs ,這點和 root 與 alias 之間的區(qū)別是保持一致的。
8.3 配置反向代理
這里為了演示更加接近實際,作者準(zhǔn)備了兩臺云服務(wù)器,它們的公網(wǎng) IP 分別是:121.42.11.34 與 121.5.180.193 。
我們把 121.42.11.34 服務(wù)器作為上游服務(wù)器,做如下配置:
# /etc/nginx/conf.d/proxy.confserver{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 服務(wù)器 nginx -s reload 。
把 121.5.180.193 服務(wù)器作為代理服務(wù)器,做如下配置:
# /etc/nginx/conf.d/proxy.confupstream 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;}}
本地機(jī)器要訪問 proxy.lion.club 域名,因此需要配置本地 hosts ,通過命令:vim /etc/hosts 進(jìn)入配置文件,添加如下內(nèi)容:
121.5.180.193?proxy.lion.club
分析:
當(dāng)訪問 proxy.lion.club/proxy 時通過 upstream 的配置找到 121.42.11.34:8080?; 因此訪問地址變?yōu)?http://121.42.11.34:8080/proxy ; 連接到 121.42.11.34 服務(wù)器,找到 8080?端口提供的 server ; 通過 server 找到?/usr/share/nginx/html/proxy/index.html 資源,最終展示出來。
8.4 配置負(fù)載均衡
配置負(fù)載均衡主要是要使用 upstream 指令。
我們把 121.42.11.34 服務(wù)器作為上游服務(wù)器,做如下配置(?/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 服務(wù)器; 執(zhí)行 ss -nlt 命令查看端口是否被占用,從而判斷 Nginx 服務(wù)是否正確啟動。
把 121.5.180.193 服務(wù)器作為代理服務(wù)器,做如下配置(?/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?服務(wù)器。并且在需要訪問的客戶端配置好 IP?和域名的映射關(guān)系。
#?/etc/hosts121.5.180.193?balance.lion.club
在客戶端機(jī)器執(zhí)行 curl http://balance.lion.club/balance/?命令:

不難看出,負(fù)載均衡的配置已經(jīng)生效了,每次給我們分發(fā)的上游服務(wù)器都不一樣。就是通過簡單的輪詢策略進(jìn)行上游服務(wù)器分發(fā)。
接下來,我們再來了解下 Nginx 的其它分發(fā)策略。
hash 算法
通過制定關(guān)鍵字作為 hash key ,基于 hash 算法映射到特定的上游服務(wù)器中。關(guān)鍵字可以包含有變量、字符串。
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ā)給同一臺服務(wù)器。
ip_hash
根據(jù)客戶端的請求 IP 進(jìn)行判斷,只要 IP 地址不變就永遠(yuǎn)分配到同一臺主機(jī)。它可以有效解決后臺服務(wù)器 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 子進(jìn)程通過讀取共享內(nèi)存的數(shù)據(jù),來獲取后端服務(wù)器的信息。來挑選一臺當(dāng)前已建立連接數(shù)最少的服務(wù)器進(jìn)行分配請求。
語法:least_conn;上下文:upstream;
示例:
upstream demo_server {zone test 10M; # zone可以設(shè)置共享內(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),負(fù)載均衡的配置其實一點都不復(fù)雜。
8.5 配置緩存
緩存可以非常有效的提升性能,因此不論是客戶端(瀏覽器),還是代理服務(wù)器( Nginx ),乃至上游服務(wù)器都多少會涉及到緩存。可見緩存在每個環(huán)節(jié)都是非常重要的。下面讓我們來學(xué)習(xí) Nginx 中如何設(shè)置緩存策略。
proxy_cache
存儲一些之前被訪問過、而且可能將要被再次訪問的資源,使用戶可以直接從代理服務(wù)器獲得,從而減少上游服務(wù)器的壓力,加快整個訪問速度。
語法:proxy_cache zone | off ; # zone 是共享內(nèi)存的名稱默認(rèn)值:proxy_cache off;上下文:http、server、location
proxy_cache_path
設(shè)置緩存文件的存放路徑。
語法:proxy_cache_path path [level=levels] ...可選參數(shù)省略,下面會詳細(xì)列舉默認(rèn)值:proxy_cache_path off上下文:http
參數(shù)含義:
path?緩存文件的存放路徑; level path?的目錄層級; keys_zone?設(shè)置共享內(nèi)存; inactive?在指定時間內(nèi)沒有被訪問,緩存會被清理,默認(rèn)10分鐘。
proxy_cache_key
設(shè)置緩存文件的 key 。
語法:proxy_cache_key默認(rèn)值: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
定義相應(yīng)保存到緩存的條件,如果字符串參數(shù)的至少一個值不為空且不等于“ 0”,則將不保存該響應(yīng)到緩存。
語法:proxy_no_cache string;上下文:http、server、location示例:proxy_no_cache $http_pragma????$http_authorization;
proxy_cache_bypass
定義條件,在該條件下將不會從緩存中獲取響應(yīng)。
語法:proxy_cache_bypass string;上下文:http、server、location示例:proxy_cache_bypass $http_pragma????$http_authorization;
upstream_cache_status 變量
它存儲了緩存是否命中的信息,會設(shè)置在響應(yīng)頭信息中,在調(diào)試中非常有用。
MISS: 未命中緩存HIT:命中緩存EXPIRED: 緩存過期STALE: 命中了陳舊緩存REVALIDDATED: Nginx驗證陳舊緩存依然有效UPDATING: 內(nèi)容陳舊,但正在更新BYPASS:?X響應(yīng)從原始服務(wù)器獲取
配置實例
我們把 121.42.11.34 服務(wù)器作為上游服務(wù)器,做如下配置(?/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 服務(wù)器作為代理服務(wù)器,做如下配置(?/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; # 設(shè)置緩存內(nèi)存,上面配置中已經(jīng)定義好的proxy_cache_valid 200 5m; # 緩存狀態(tài)為200的請求,緩存時長為5分鐘proxy_cache_key $request_uri; # 緩存文件的key為請求的URIadd_header Nginx-Cache-Status $upstream_cache_status # 把緩存狀態(tài)設(shè)置為頭部信息,響應(yīng)給客戶端proxy_pass http://cache_server; # 代理轉(zhuǎn)發(fā)}}
緩存就是這樣配置,我們可以在?/etc/nginx/cache_temp 路徑下找到相應(yīng)的緩存文件。
對于一些實時性要求非常高的頁面或數(shù)據(jù)來說,就不應(yīng)該去設(shè)置緩存,下面來看看如何配置不緩存的內(nèi)容。
...server {listen 80;server_name cache.lion.club;# URI 中后綴為 .txt 或 .text 的設(shè)置變量值為 "no cache"if ($request_uri ~ \.(txt|text)$) {set $cache_name "no cache"}location / {proxy_no_cache $cache_name; # 判斷該變量是否有值,如果有值則不進(jìn)行緩存,如果沒有值則進(jìn)行緩存proxy_cache cache_zone; # 設(shè)置緩存內(nèi)存proxy_cache_valid 200 5m; # 緩存狀態(tài)為200的請求,緩存時長為5分鐘proxy_cache_key $request_uri; # 緩存文件的key為請求的URIadd_header Nginx-Cache-Status $upstream_cache_status # 把緩存狀態(tài)設(shè)置為頭部信息,響應(yīng)給客戶端proxy_pass http://cache_server; # 代理轉(zhuǎn)發(fā)}}
8.6 HTTPS
在學(xué)習(xí)如何配置 HTTPS 之前,我們先來簡單回顧下 HTTPS 的工作流程是怎么樣的?它是如何進(jìn)行加密保證安全的?
HTTPS 工作流程
客戶端(瀏覽器)訪問 https://www.baidu.com 百度網(wǎng)站; 百度服務(wù)器返回 HTTPS 使用的 CA 證書; 瀏覽器驗證 CA 證書是否為合法證書; 驗證通過,證書合法,生成一串隨機(jī)數(shù)并使用公鑰(證書中提供的)進(jìn)行加密; 發(fā)送公鑰加密后的隨機(jī)數(shù)給百度服務(wù)器; 百度服務(wù)器拿到密文,通過私鑰進(jìn)行解密,獲取到隨機(jī)數(shù)(公鑰加密,私鑰解密,反之也可以); 百度服務(wù)器把要發(fā)送給瀏覽器的內(nèi)容,使用隨機(jī)數(shù)進(jìn)行加密后傳輸給瀏覽器; 此時瀏覽器可以使用隨機(jī)數(shù)進(jìn)行解密,獲取到服務(wù)器的真實傳輸內(nèi)容;
這就是 HTTPS 的基本運(yùn)作原理,使用對稱加密和非對稱機(jī)密配合使用,保證傳輸內(nèi)容的安全性。
配置證書
下載證書的壓縮文件,里面有個 Nginx 文件夾,把 xxx.crt 和 xxx.key 文件拷貝到服務(wù)器目錄,再進(jìn)行如下配置:
server {listen 443 ssl http2 default_server; # SSL 訪問端口號為 443server_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é)議版本,默認(rèn)為后三個,主流版本是[TLSv1.2]location / {root /usr/share/nginx/html;index index.html index.htm;}}
如此配置后就能正常訪問 HTTPS 版的網(wǎng)站了。
8.7 配置跨域 CORS
先簡單回顧下跨域究竟是怎么回事。
跨域的定義
同源策略限制了從同一個源加載的文檔或腳本如何與來自另一個源的資源進(jìn)行交互。這是一個用于隔離潛在惡意文件的重要安全機(jī)制。通常不允許不同源間的讀操作。
同源的定義
如果兩個頁面的協(xié)議,端口(如果有指定)和域名都相同,則兩個頁面具有相同的源。
下面給出了與 URL http://store.company.com/dir/page.html 的源進(jìn)行對比的示例:
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?不同源,主機(jī)不同
不同源會有如下限制:
Web 數(shù)據(jù)層面,同源策略限制了不同源的站點讀取當(dāng)前站點的 Cookie 、 IndexDB 、 LocalStorage 等數(shù)據(jù); DOM 層面,同源策略限制了來自不同源的 JavaScript 腳本對當(dāng)前 DOM 對象讀和寫的操作; 網(wǎng)絡(luò)層面,同源策略限制了通過 XMLHttpRequest 等方式將站點的數(shù)據(jù)發(fā)送給不同源的站點。
Nginx 解決跨域的原理
例如:
前端 server 的域名為:fe.server.com 后端服務(wù)的域名為:dev.server.com
現(xiàn)在我在 fe.server.com 對 dev.server.com 發(fā)起請求一定會出現(xiàn)跨域。
現(xiàn)在我們只需要啟動一個 Nginx 服務(wù)器,將 server_name 設(shè)置為 fe.server.com 然后設(shè)置相應(yīng)的 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 對服務(wù)端轉(zhuǎn)發(fā)的請求不會觸發(fā)瀏覽器的同源策略。
8.8 配置開啟 gzip 壓縮
GZIP 是規(guī)定的三種標(biāo)準(zhǔn) HTTP 壓縮格式之一。目前絕大多數(shù)的網(wǎng)站都在使用 GZIP 傳輸 HTML 、CSS 、 JavaScript 等資源文件。
對于文本文件, GZiP 的效果非常明顯,開啟后傳輸所需流量大約會降至 1/4~1/3 。
并不是每個瀏覽器都支持 gzip 的,如何知道客戶端是否支持 gzip 呢,請求頭中的 Accept-Encoding 來標(biāo)識對壓縮的支持。

啟用 gzip 同時需要客戶端和服務(wù)端的支持,如果客戶端支持 gzip 的解析,那么只要服務(wù)端能夠返回 gzip 的文件就可以啟用 gzip 了,我們可以通過 Nginx 的配置來讓服務(wù)端支持 gzip 。下面的 respone 中 content-encoding:gzip ,指服務(wù)端開啟了 gzip 的壓縮方式。

在?/etc/nginx/conf.d/?文件夾中新建配置文件 gzip.conf :
# # 默認(rèn)off,是否開啟gzipgzip on;# 要采用 gzip 壓縮的 MIME 文件類型,其中 text/html 被系統(tǒng)強(qiáng)制啟用;gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;# ---- 以上兩個參數(shù)開啟就可以支持Gzip壓縮了 ---- ## 默認(rèn) off,該模塊啟用后,Nginx 首先檢查是否存在請求靜態(tài)文件的 gz 結(jié)尾的文件,如果有則直接返回該 .gz 文件內(nèi)容;gzip_static on;# 默認(rèn) off,nginx做為反向代理時啟用,用于設(shè)置啟用或禁用從代理服務(wù)器上收到相應(yīng)內(nèi)容 gzip 壓縮;gzip_proxied any;# 用于在響應(yīng)消息頭中添加 Vary:Accept-Encoding,使代理服務(wù)器根據(jù)請求頭中的 Accept-Encoding 識別是否啟用 gzip 壓縮;gzip_vary on;# gzip 壓縮比,壓縮級別是 1-9,1 壓縮級別最低,9 最高,級別越高壓縮率越大,壓縮時間越長,建議 4-6;gzip_comp_level 6;# 獲取多少內(nèi)存用于緩存壓縮結(jié)果,16 8k 表示以 8k*16 為單位獲得;gzip_buffers 16 8k;# 允許壓縮的頁面最小字節(jié)數(shù),頁面字節(jié)數(shù)從header頭中的 Content-Length 中進(jìn)行獲取。默認(rèn)值是 0,不管頁面多大都壓縮。建議設(shè)置成大于 1k 的字節(jié)數(shù),小于 1k 可能會越壓越大;# gzip_min_length 1k;# 默認(rèn) 1.1,啟用 gzip 所需的 HTTP 最低版本;gzip_http_version?1.1;
其實也可以通過前端構(gòu)建工具例如 webpack 、rollup 等在打生產(chǎn)包時就做好 Gzip 壓縮,然后放到 Nginx 服務(wù)器中,這樣可以減少服務(wù)器的開銷,加快訪問速度。
關(guān)于 Nginx 的實際應(yīng)用就學(xué)習(xí)到這里,相信通過掌握了 Nginx 核心配置以及實戰(zhàn)配置,之后再遇到什么需求,我們也能輕松應(yīng)對。接下來,讓我們再深入一點學(xué)習(xí)下 Nginx 的架構(gòu)。
9. Nginx 架構(gòu)
9.1 進(jìn)程結(jié)構(gòu)
多進(jìn)程結(jié)構(gòu) Nginx 的進(jìn)程模型圖:

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

總結(jié)
相信通過本文的學(xué)習(xí),你應(yīng)該會對 Nginx 有一個更加全面的認(rèn)識。
?推薦閱讀? 31天拿下K8s含金量最高的CKA+CKS證書!? 7 款 DevOps 工具管理 Kubernetes Linux 根分區(qū)快滿了,這個方法快速定位! 自從上了 Prometheus,睡覺也踏實了! 一文搞懂 Kubernetes 網(wǎng)絡(luò)通信原理 Shell 編程的經(jīng)典十三問!老司機(jī)也會翻車 SRE本質(zhì)就是一個懂運(yùn)維的資深開發(fā) Kubernetes 4000節(jié)點運(yùn)維經(jīng)驗分享 從網(wǎng)管到架構(gòu)師,給你分享這10年的成長感悟 Kubernetes 的高級部署策略,你不一定知道! 9個常用的Shell腳本,面試也常問! 基于Nginx實現(xiàn)灰度發(fā)布與AB測試 搭建一套完整的企業(yè)級 K8s 集群(v1.22,二進(jìn)制方式) 點亮,服務(wù)器三年不宕機(jī)


