作為一名開發人員,你是不是經常碰到領導讓你上服務器去修改 Nginx 配置,然而你可能會對這些配置並不熟悉!今天就讓我們一起告別這種尷尬,向「真正」的程序員邁進!!!
如果本文對你有所幫助,請點個👍 👍 👍 吧!
Nginx 概述
Nginx 是開源、高性能、高可靠的 Web 和反向代理服務器,而且支持熱部署,幾乎可以做到 7 * 24 小時不間斷運行,即使運行幾個月也不需要重新啟動,還能在不間斷服務的情況下對軟件版本進行熱更新。性能是 Nginx 最重要的考量,其占用內存少、並發能力強、能支持高達 5w 個並發連接數,最重要的是, Nginx 是免費的並可以商業化,配置使用也比較簡單。
Nginx 特點Nginx 的最重要的幾個使用場景:
對於前端來說 Node.js 並不陌生, Nginx 和 Node.js 的很多理念類似, HTTP 服務器、事件驅動、異步非阻塞等,且 Nginx 的大部分功能使用 Node.js 也可以實現,但 Nginx 和 Node.js 並不衝突,都有自己擅長的領域。Nginx 擅長於底層服務器端資源的處理(靜態資源處理轉發、反向代理,負載均衡等), Node.js 更擅長上層具體業務邏輯的處理,兩者可以完美組合。
用一張圖表示:
本文演示的是 Linux centOS 7.x 的操作系統上安裝 Nginx ,至於在其它操作系統上進行安裝可以網上自行搜索,都非常簡單的。
使用 yum 安裝 Nginx :
yuminstallnginx-y複製代碼安裝完成後,通過 rpm -ql nginx 命令查看 Nginx 的安裝信息:
#Nginx配置文件/etc/nginx/nginx.conf#nginx主配置文件/etc/nginx/nginx.conf.default#可執行程序文件/usr/bin/nginx-upgrade/usr/sbin/nginx#nginx庫文件/usr/lib/systemd/system/nginx.service#用於配置系統守護進程/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#靜態資源目錄/usr/share/nginx/html/404.html/usr/share/nginx/html/50x.html/usr/share/nginx/html/index.html#存放Nginx日誌文件/var/log/nginx複製代碼主要關注的文件夾有兩個:
systemctl 系統命令:
#開機配置systemctlenablenginx#開機自動啟動systemctldisablenginx#關閉開機自動啟動#啟動Nginxsystemctlstartnginx#啟動Nginx成功後,可以直接訪問主機IP,此時會展示Nginx默認頁面#停止Nginxsystemctlstopnginx#重啟Nginxsystemctlrestartnginx#重新加載Nginxsystemctlreloadnginx#查看Nginx運行狀態systemctlstatusnginx#查看Nginx進程ps-ef|grepnginx#殺死Nginx進程kill-9pid#根據上面查看到的Nginx進程號,殺死Nginx進程,-9表示強制結束進程複製代碼Nginx 應用程序命令:
nginx-sreload#向主進程發送信號,重新加載配置文件,熱重啟nginx-sreopen#重啟Nginxnginx-sstop#快速關閉nginx-squit#等待工作進程處理完成後關閉nginx-T#查看當前Nginx最終的配置nginx-t#檢查配置是否有問題複製代碼Nginx 核心配置
配置文件結構Nginx 的典型配置示例:
#main段配置信息usernginx;#運行用戶,默認即是nginx,可以不進行設置worker_processesauto;#Nginx進程數,一般設置為和CPU核數一樣error_log/var/log/nginx/error.logwarn;#Nginx的錯誤日誌存放目錄pid/var/run/nginx.pid;#Nginx服務啟動時的pid存放位置#events段配置信息events{useepoll;#使用epoll的I/O模型(如果你不知道Nginx該使用哪種輪詢方法,會自動選擇一個最適合你操作系統的)worker_connections1024;#每個進程允許最大並發數}#http段配置信息#配置使用最頻繁的部分,代理、緩存、日誌定義等絕大多數功能和第三方模塊的配置都在這裡設置http{#設置日誌模式log_formatmain'$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.logmain;#Nginx訪問日誌存放位置sendfileon;#開啟高效傳輸模式tcp_nopushon;#減少網絡報文段的數量tcp_nodelayon;keepalive_timeout65;#保持連接的時間,也叫超時時間,單位秒types_hash_max_size2048;include/etc/nginx/mime.types;#文件擴展名與類型映射表default_typeapplication/octet-stream;#默認文件類型include/etc/nginx/conf.d/*.conf;#加載子配置項#server段配置信息server{listen80;#配置監聽的端口server_namelocalhost;#配置的域名#location段配置信息location/{root/usr/share/nginx/html;#網站根目錄indexindex.htmlindex.htm;#默認首頁文件deny172.168.22.11;#禁止訪問的ip地址,可以為all allow 172.168.33.44;#允許訪問的ip地址,可以為all}error_page500502503504/50x.html;#默認50x對應的訪問頁面error_page400404error.html;#同上}}複製代碼用一張圖清晰的展示它的層級結構:
指定運行 Nginx 的 woker 子進程的屬主和屬組,其中組可以不指定。
userUSERNAME[GROUP]usernginxlion;#用戶是nginx;組是lion複製代碼pid指定運行 Nginx master 主進程的 pid 文件存放路徑。
pid/opt/nginx/logs/nginx.pid#master主進程的的pid存放在nginx.pid的文件複製代碼worker_rlimit_nofile_number指定 worker 子進程可以打開的最大文件句柄數。
worker_rlimit_nofile20480;#可以理解成每個worker子進程的最大連接數量。複製代碼worker_rlimit_core指定 worker 子進程異常終止後的 core 文件,用於記錄分析問題。
worker_rlimit_core50M;#存放大小限制working_directory/opt/nginx/tmp;#存放目錄複製代碼worker_processes_number指定 Nginx 啟動的 worker 子進程數量。
worker_processes4;#指定具體子進程數量worker_processesauto;#與當前cpu物理核心數一致複製代碼worker_cpu_affinity將每個 worker 子進程與我們的 cpu 物理核心綁定。
worker_cpu_affinity0001001001001000;#4個物理核心,4個worker子進程複製代碼
將每個 worker 子進程與特定 CPU 物理核心綁定,優勢在於,避免同一個 worker 子進程在不同的 CPU 核心上切換,緩存失效,降低性能。但其並不能真正的避免進程切換。
worker_priority指定 worker 子進程的 nice 值,以調整運行 Nginx 的優先級,通常設定為負值,以優先調用 Nginx 。
worker_priority-10;#120-10=110,110就是最終的優先級複製代碼Linux 默認進程的優先級值是120,值越小越優先;nice 定範圍為 -20 到 +19 。
[備註] 應用的默認優先級值是120加上 nice 值等於它最終的值,這個值越小,優先級越高。
worker_shutdown_timeout指定 worker 子進程優雅退出時的超時時間。
worker_shutdown_timeout5s;複製代碼timer_resolutionworker 子進程內部使用的計時器精度,調整時間間隔越大,系統調用越少,有利於性能提升;反之,系統調用越多,性能下降。
timer_resolution100ms;複製代碼在 Linux 系統中,用戶需要獲取計時器時需要向操作系統內核發送請求,有請求就必然會有開銷,因此這個間隔越大開銷就越小。
daemon指定 Nginx 的運行方式,前台還是後台,前台用於調試,後台用於生產。
daemonoff;#默認是on,後台運行模式複製代碼配置文件 events 段核心參數useNginx 使用何種事件驅動模型。
usemethod;#不推薦配置它,讓nginx自己選擇method 可選值為:select、poll、kqueue、epoll、/dev/poll、eventport複製代碼worker_connectionsworker 子進程能夠處理的最大並發連接數。
worker_connections1024#每個子進程的最大連接數為1024複製代碼accept_mutex是否打開負載均衡互斥鎖。
accept_mutexon#默認是off關閉的,這裡推薦打開複製代碼server_name 指令指定虛擬主機域名。
server_namename1name2name3#示例:server_namewww.nginx.com;複製代碼域名匹配的四種寫法:
匹配優先級:精確匹配 > 左側通配符匹配 > 右側通配符匹配 > 正則表達式匹配
server_name 配置實例:
1、配置本地 DNS 解析 vim /etc/hosts ( macOS 系統)
#添加如下內容,其中121.42.11.34是阿里雲服務器IP地址121.42.11.34www.nginx-test.com121.42.11.34mail.nginx-test.com121.42.11.34www.nginx-test.org121.42.11.34doc.nginx-test.com121.42.11.34www.nginx-test.cn121.42.11.34fe.nginx-test.club複製代碼[注意] 這裡使用的是虛擬域名進行測試,因此需要配置本地 DNS 解析,如果使用阿里雲上購買的域名,則需要在阿里雲上設置好域名解析。
2、配置阿里雲 Nginx ,vim /etc/nginx/nginx.conf
#這裡只列舉了http端中的sever端配置#左匹配server{listen80;server_name*.nginx-test.com;root/usr/share/nginx/html/nginx-test/left-match/;location/{indexindex.html;}}#正則匹配server{listen80;server_name~^.*\.nginx-test\..*$;root/usr/share/nginx/html/nginx-test/reg-match/;location/{indexindex.html;}}#右匹配server{listen80;server_namewww.nginx-test.*;root/usr/share/nginx/html/nginx-test/right-match/;location/{indexindex.html;}}#完全匹配server{listen80;server_namewww.nginx-test.com;root/usr/share/nginx/html/nginx-test/all-match/;location/{indexindex.html;}}複製代碼3、訪問分析
指定靜態資源目錄位置,它可以寫在 http 、 server 、 location 等配置中。
rootpath例如:location/image{root/opt/nginx/static;}當用戶訪問www.test.com/image/1.png時,實際在服務器找的路徑是/opt/nginx/static/image/1.png複製代碼[注意] root 會將定義路徑與 URI 疊加, alias 則只取定義路徑。
alias它也是指定靜態資源目錄位置,它只能寫在 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{...}複製代碼匹配規則:
匹配優先級:= > ^~ > ~ > ~* > 不帶任何字符。
實例:
server{listen80;server_namewww.nginx-test.com;#只有當訪問www.nginx-test.com/match_all/時才會匹配到/usr/share/nginx/html/match_all/index.htmllocation=/match_all/{root/usr/share/nginx/htmlindexindex.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.htmllocation^~/bbs/{root/usr/share/nginx/html;indexindex.htmlindex.htm;}}複製代碼location 中的反斜線location/test{...}location/test/{...}複製代碼停止處理請求,直接返迴響應碼或重定向到其他 URL ;執行 return 指令後, location 中後續指令將不會被執行。
returncode[text];returncodeURL;returnURL;例如:location/{return404;#直接返回狀態碼}location/{return404"pagesnotfound";#返回狀態碼+一段文本}location/{return302/bbs;#返回狀態碼+重定向地址}location/{returnhttps://www.baidu.com;#返回重定向地址}複製代碼rewrite根據指定正則表達式匹配規則,重寫 URL 。
語法:rewrite 正則表達式要替換的內容[flag];上下文:server、location、if示例:rewirte /images/(.*\.jpg)$/pic/$1;#$1是前面括號(.*\.jpg)的反向引用複製代碼flag 可選值的含義:
按照這個配置我們來分析:
condition 判斷條件:
實例:
server{listen8080;server_namelocalhost;roothtml;location/{if($uri="/images/"){rewrite(.*)/pics/break;}}}複製代碼當訪問 localhost:8080/images/ 時,會進入 if 判斷裡面執行 rewrite 命令。
autoindex用戶請求以 / 結尾時,列出目錄結構,可以用於快速搭建靜態資源下載網站。
autoindex.conf 配置信息:
server{listen80;server_namefe.lion-test.club;location/download/{root/opt/source;autoindexon;#打開autoindex,,可選參數有on|offautoindex_exact_sizeon;#修改為off,以KB、MB、GB顯示文件大小,默認為on,以bytes顯示出⽂件的確切⼤⼩autoindex_formathtml;#以html的方式進行格式化,可選參數有html|json|xmlautoindex_localtimeoff;#顯示的⽂件時間為⽂件的服務器時間。默認為off,顯示的⽂件時間為GMT時間}}複製代碼當訪問 fe.lion.com/download/ 時,會把服務器 /opt/source/download/ 路徑下的文件展示出來,如下圖所示:

Nginx 提供給使用者的變量非常多,但是終究是一個完整的請求過程所產生數據, Nginx 將這些數據以變量的形式提供給使用者。
下面列舉些項目中常用的變量:
實例演示 var.conf :
server{listen8081;server_namevar.lion-test.club;root/usr/share/nginx/html;location/{return200"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";}}複製代碼當我們訪問 http://var.lion-test.club:8081/test?pid=121414&cid=sadasd 時,由於 Nginx 中寫了 return 方法,因此 chrome 瀏覽器會默認為我們下載一個文件,下面展示的就是下載的文件內容:
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;IntelMacOSX10_14_0)AppleWebKit/537.36(KHTML,likeGecko)Chrome/88.0.4324.182Safari/537.36http_referer:http_via:request_time:0.000https:request_filename:/usr/share/nginx/html/test/document_root:/usr/share/nginx/html複製代碼Nginx 的配置還有非常多,以上只是羅列了一些常用的配置,在實際項目中還是要學會查閱文檔。
Nginx 應用核心概念代理是在服務器和客戶端之間假設的一層服務器,代理將接收客戶端的請求並將它轉發給服務器,然後將服務端的響應轉發給客戶端。
不管是正向代理還是反向代理,實現的都是上面的功能。

正向代理,意思是一個位於客戶端和原始服務器(origin server)之間的服務器,為了從原始服務器取得內容,客戶端向代理髮送一個請求並指定目標(原始服務器),然後代理向原始服務器轉交請求並將獲得的內容返回給客戶端。
正向代理是為我們服務的,即為客戶端服務的,客戶端可以根據正向代理訪問到它本身無法訪問到的服務器資源。
正向代理對我們是透明的,對服務端是非透明的,即服務端並不知道自己收到的是來自代理的訪問還是來自真實客戶端的訪問。
反向代理反向代理是為服務端服務的,反向代理可以幫助服務器接收來自客戶端的請求,幫助服務器做請求轉發,負載均衡等。
反向代理對服務端是透明的,對我們是非透明的,即我們並不知道自己訪問的是代理服務器,而服務器知道反向代理在為他服務。
反向代理的優勢:
那麼「動靜分離」是什麼?負載均衡又是什麼?
動靜分離動靜分離是指在 web 服務器架構中,將靜態頁面與動態頁面或者靜態內容接口和動態內容接口分開不同系統訪問的架構設計方法,進而提示整個服務的訪問性和可維護性。

一般來說,都需要將動態資源和靜態資源分開,由於 Nginx 的高並發和靜態資源緩存等特性,經常將靜態資源部署在 Nginx 上。如果請求的是靜態資源,直接到靜態資源目錄獲取資源,如果是動態資源的請求,則利用反向代理的原理,把請求轉發給對應後台應用去處理,從而實現動靜分離。
使用前後端分離後,可以很大程度提升靜態資源的訪問速度,即使動態服務不可用,靜態資源的訪問也不會受到影響。
負載均衡一般情況下,客戶端發送多個請求到服務器,服務器處理請求,其中一部分可能要操作一些資源比如數據庫、靜態資源等,服務器處理完畢後,再將結果返回給客戶端。
這種模式對於早期的系統來說,功能要求不複雜,且並發請求相對較少的情況下還能勝任,成本也低。隨着信息數量不斷增長,訪問量和數據量飛速增長,以及系統業務複雜度持續增加,這種做法已無法滿足要求,並發量特別大時,服務器容易崩。
很明顯這是由於服務器性能的瓶頸造成的問題,除了堆機器之外,最重要的做法就是負載均衡。
請求爆發式增長的情況下,單個機器性能再強勁也無法滿足要求了,這個時候集群的概念產生了,單個服務器解決不了的問題,可以使用多個服務器,然後將請求分發到各個服務器上,將負載分發到不同的服務器,這就是負載均衡,核心是「分攤壓力」。Nginx 實現負載均衡,一般來說指的是將請求轉發給服務器集群。
舉個具體的例子,晚高峰乘坐地鐵的時候,入站口經常會有地鐵工作人員大喇叭「請走 B 口, B 口人少車空....」,這個工作人員的作用就是負載均衡。
Nginx 實現負載均衡的策略:
Nginx 實戰配置
在配置反向代理和負載均衡等等功能之前,有兩個核心模塊是我們必須要掌握的,這兩個模塊應該說是 Nginx 應用配置中的核心,它們分別是:upstream 、proxy_pass 。
upstream用於定義上游服務器(指的就是後台提供的應用服務器)的相關信息。

在 upstream 內可使用的指令:
定義上游服務器地址。
語法:server address [parameters]上下文:upstream複製代碼parameters 可選值:
限制每個 worker 子進程與上游服務器空閒長連接的最大數量。
keepaliveconnections;上下文:upstream示例:keepalive 16;複製代碼keepalive_requests單個長連接可以處理的最多 HTTP 請求個數。
語法:keepalive_requests number;默認值:keepalive_requests 100;上下文:upstream複製代碼keepalive_timeout空閒長連接的最長保持時間。
語法:keepalive_timeout time;默認值:keepalive_timeout 60s;上下文:upstream複製代碼配置實例upstreamback_end{server127.0.0.1:8081weight=3max_conns=1000fail_timeout=10smax_fails=2;keepalive32;keepalive_requests50;keepalive_timeout30s;}複製代碼proxy_pass用於配置代理服務器。
語法:proxy_pass URL;上下文:location、if、limit_except示例:proxy_passhttp://127.0.0.1:8081proxy_passhttp://127.0.0.1:8081/proxy複製代碼URL 參數原則
接下來讓我們來看看兩種常見的 URL 用法:
這兩種用法的區別就是帶 / 和不帶 / ,在配置代理時它們的區別可大了:
不帶 / 的用法:
location/bbs/{proxy_passhttp://127.0.0.1:8080;}複製代碼分析:
帶 / 的用法:
location/bbs/{proxy_passhttp://127.0.0.1:8080/;}複製代碼分析:
並沒有拼接上 /bbs ,這點和 root 與 alias 之間的區別是保持一致的。
配置反向代理這裡為了演示更加接近實際,作者準備了兩台雲服務器,它們的公網 IP 分別是:121.42.11.34 與 121.5.180.193 。
我們把 121.42.11.34 服務器作為上游服務器,做如下配置:
#/etc/nginx/conf.d/proxy.confserver{listen8080;server_namelocalhost;location/proxy/{root/usr/share/nginx/html/proxy;indexindex.html;}}#/usr/share/nginx/html/proxy/index.html<h1>121.42.11.34proxyhtml</h1>複製代碼配置完成後重啟 Nginx 服務器 nginx -s reload 。
把 121.5.180.193 服務器作為代理服務器,做如下配置:
#/etc/nginx/conf.d/proxy.confupstreamback_end{server121.42.11.34:8080weight=2max_conns=1000fail_timeout=10smax_fails=3;keepalive32;keepalive_requests80;keepalive_timeout20s;}server{listen80;server_nameproxy.lion.club;location/proxy{proxy_passhttp://back_end/proxy;}}複製代碼本地機器要訪問 proxy.lion.club 域名,因此需要配置本地 hosts ,通過命令:vim /etc/hosts 進入配置文件,添加如下內容:
121.5.180.193proxy.lion.club複製代碼
分析:
配置負載均衡主要是要使用 upstream 指令。
我們把 121.42.11.34 服務器作為上游服務器,做如下配置( /etc/nginx/conf.d/balance.conf ):
server{listen8020;location/{return200'return8020\n';}}server{listen8030;location/{return200'return8030\n';}}server{listen8040;location/{return200'return8040\n';}}複製代碼配置完成後:
把 121.5.180.193 服務器作為代理服務器,做如下配置( /etc/nginx/conf.d/balance.conf ):
upstreamdemo_server{server121.42.11.34:8020;server121.42.11.34:8030;server121.42.11.34:8040;}server{listen80;server_namebalance.lion.club;location/balance/{proxy_passhttp://demo_server;}}複製代碼配置完成後重啟 Nginx 服務器。並且在需要訪問的客戶端配置好 ip 和域名的映射關係。
#/etc/hosts121.5.180.193balance.lion.club複製代碼在客戶端機器執行 curl http://balance.lion.club/balance/ 命令:

不難看出,負載均衡的配置已經生效了,每次給我們分發的上游服務器都不一樣。就是通過簡單的輪詢策略進行上游服務器分發。
接下來,我們再來了解下 Nginx 的其它分發策略。
hash 算法通過制定關鍵字作為 hash key ,基於 hash 算法映射到特定的上游服務器中。關鍵字可以包含有變量、字符串。
upstreamdemo_server{hash$request_uri;server121.42.11.34:8020;server121.42.11.34:8030;server121.42.11.34:8040;}server{listen80;server_namebalance.lion.club;location/balance/{proxy_passhttp://demo_server;}}複製代碼hash $request_uri 表示使用 request_uri 變量作為 hash 的 key 值,只要訪問的 URI 保持不變,就會一直分發給同一台服務器。
ip_hash根據客戶端的請求 ip 進行判斷,只要 ip 地址不變就永遠分配到同一台主機。它可以有效解決後台服務器 session 保持的問題。
upstreamdemo_server{ip_hash;server121.42.11.34:8020;server121.42.11.34:8030;server121.42.11.34:8040;}server{listen80;server_namebalance.lion.club;location/balance/{proxy_passhttp://demo_server;}}複製代碼最少連接數算法各個 worker 子進程通過讀取共享內存的數據,來獲取後端服務器的信息。來挑選一台當前已建立連接數最少的服務器進行分配請求。
語法:least_conn;上下文:upstream;複製代碼示例:
upstreamdemo_server{zonetest10M;#zone可以設置共享內存空間的名字和大小least_conn;server121.42.11.34:8020;server121.42.11.34:8030;server121.42.11.34:8040;}server{listen80;server_namebalance.lion.club;location/balance/{proxy_passhttp://demo_server;}}複製代碼最後你會發現,負載均衡的配置其實一點都不複雜。
配置緩存緩存可以非常有效的提升性能,因此不論是客戶端(瀏覽器),還是代理服務器( Nginx ),乃至上游服務器都多少會涉及到緩存。可見緩存在每個環節都是非常重要的。下面讓我們來學習 Nginx 中如何設置緩存策略。
proxy_cache存儲一些之前被訪問過、而且可能將要被再次訪問的資源,使用戶可以直接從代理服務器獲得,從而減少上游服務器的壓力,加快整個訪問速度。
語法:proxy_cache zone | off ;#zone是共享內存的名稱默認值:proxy_cache off;上下文:http、server、location複製代碼proxy_cache_path設置緩存文件的存放路徑。
語法:proxy_cache_path path [level=levels] ...可選參數省略,下面會詳細列舉默認值:proxy_cache_path off上下文:http複製代碼參數含義:
設置緩存文件的 key 。
語法:proxy_cache_key默認值:proxy_cache_key $scheme$proxy_host$request_uri;上下文:http、server、location複製代碼proxy_cache_valid配置什麼狀態碼可以被緩存,以及緩存時長。
語法:proxy_cache_valid [code...] time;上下文:http、server、location配置示例:proxy_cache_valid 200 304 2m;;#說明對於狀態為200和304的緩存文件的緩存時間是2分鐘複製代碼proxy_no_cache定義相應保存到緩存的條件,如果字符串參數的至少一個值不為空且不等於「 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 變量它存儲了緩存是否命中的信息,會設置在響應頭信息中,在調試中非常有用。
MISS:未命中緩存HIT:命中緩存EXPIRED:緩存過期STALE:命中了陳舊緩存REVALIDDATED:Nginx驗證陳舊緩存依然有效UPDATING:內容陳舊,但正在更新BYPASS:X響應從原始服務器獲取複製代碼配置實例我們把 121.42.11.34 服務器作為上游服務器,做如下配置( /etc/nginx/conf.d/cache.conf ):
server{listen1010;root/usr/share/nginx/html/1010;location/{indexindex.html;}}server{listen1020;root/usr/share/nginx/html/1020;location/{indexindex.html;}}複製代碼把 121.5.180.193 服務器作為代理服務器,做如下配置( /etc/nginx/conf.d/cache.conf ):
proxy_cache_path/etc/nginx/cache_templevels=2:2keys_zone=cache_zone:30mmax_size=2ginactive=60muse_temp_path=off;upstreamcache_server{server121.42.11.34:1010;server121.42.11.34:1020;}server{listen80;server_namecache.lion.club;location/{proxy_cachecache_zone;#設置緩存內存,上面配置中已經定義好的proxy_cache_valid2005m;#緩存狀態為200的請求,緩存時長為5分鐘proxy_cache_key$request_uri;#緩存文件的key為請求的URIadd_headerNginx-Cache-Status$upstream_cache_status#把緩存狀態設置為頭部信息,響應給客戶端proxy_passhttp://cache_server;#代理轉發}}複製代碼緩存就是這樣配置,我們可以在 /etc/nginx/cache_temp 路徑下找到相應的緩存文件。
對於一些實時性要求非常高的頁面或數據來說,就不應該去設置緩存,下面來看看如何配置不緩存的內容。
...server{listen80;server_namecache.lion.club;#URI中後綴為.txt或.text的設置變量值為"nocache"if($request_uri~\.(txt|text)$){set$cache_name"nocache"}location/{proxy_no_cache$cache_name;#判斷該變量是否有值,如果有值則不進行緩存,如果沒有值則進行緩存proxy_cachecache_zone;#設置緩存內存proxy_cache_valid2005m;#緩存狀態為200的請求,緩存時長為5分鐘proxy_cache_key$request_uri;#緩存文件的key為請求的URIadd_headerNginx-Cache-Status$upstream_cache_status#把緩存狀態設置為頭部信息,響應給客戶端proxy_passhttp://cache_server;#代理轉發}}複製代碼HTTPS在學習如何配置 HTTPS 之前,我們先來簡單回顧下 HTTPS 的工作流程是怎麼樣的?它是如何進行加密保證安全的?
HTTPS 工作流程這就是 HTTPS 的基本運作原理,使用對稱加密和非對稱機密配合使用,保證傳輸內容的安全性。
關於HTTPS更多知識,可以查看作者的另外一篇文章《學習 HTTP 協議》。
配置證書下載證書的壓縮文件,裡面有個 Nginx 文件夾,把 xxx.crt 和 xxx.key 文件拷貝到服務器目錄,再進行如下配置:
server{listen443sslhttp2default_server;#SSL訪問端口號為443server_namelion.club;#填寫綁定證書的域名(我這裡是隨便寫的)ssl_certificate/etc/nginx/https/lion.club_bundle.crt;#證書地址ssl_certificate_key/etc/nginx/https/lion.club.key;#私鑰地址ssl_session_timeout10m;ssl_protocolsTLSv1TLSv1.1TLSv1.2;#支持ssl協議版本,默認為後三個,主流版本是[TLSv1.2]location/{root/usr/share/nginx/html;indexindex.htmlindex.htm;}}複製代碼如此配置後就能正常訪問 HTTPS 版的網站了。
配置跨域 CORS先簡單回顧下跨域究竟是怎麼回事。
跨域的定義同源策略限制了從同一個源加載的文檔或腳本如何與來自另一個源的資源進行交互。這是一個用於隔離潛在惡意文件的重要安全機制。通常不允許不同源間的讀操作。
同源的定義如果兩個頁面的協議,端口(如果有指定)和域名都相同,則兩個頁面具有相同的源。
下面給出了與 URL http://store.company.com/dir/page.html 的源進行對比的示例:
http://store.company.com/dir2/other.html同源https://store.company.com/secure.html不同源,協議不同http://store.company.com:81/dir/etc.html不同源,端口不同http://news.company.com/dir/other.html不同源,主機不同複製代碼不同源會有如下限制:
例如:
現在我在 fe.server.com 對 dev.server.com 發起請求一定會出現跨域。
現在我們只需要啟動一個 Nginx 服務器,將 server_name 設置為 fe.server.com 然後設置相應的 location 以攔截前端需要跨域的請求,最後將請求代理回 dev.server.com 。如下面的配置:
server{listen80;server_namefe.server.com;location/{proxy_passdev.server.com;}}複製代碼這樣可以完美繞過瀏覽器的同源策略:fe.server.com 訪問 Nginx 的 fe.server.com 屬於同源訪問,而 Nginx 對服務端轉發的請求不會觸發瀏覽器的同源策略。
配置開啟 gzip 壓縮GZIP 是規定的三種標準 HTTP 壓縮格式之一。目前絕大多數的網站都在使用 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 :
其實也可以通過前端構建工具例如 webpack 、rollup 等在打生產包時就做好 Gzip 壓縮,然後放到 Nginx 服務器中,這樣可以減少服務器的開銷,加快訪問速度。
關於 Nginx 的實際應用就學習到這裡,相信通過掌握了 Nginx 核心配置以及實戰配置,之後再遇到什麼需求,我們也能輕鬆應對。接下來,讓我們再深入一點學習下 Nginx 的架構。
Nginx 架構進程結構多進程結構 Nginx 的進程模型圖:

多進程中的 Nginx 進程架構如下圖所示,會有一個父進程( Master Process ),它會有很多子進程( Child Processes )。
用來管理子進程的,其本身並不真正處理用戶請求。
子進程間是通過共享內存的方式進行通信的。
reload 重載配置文件的流程:
Nginx 的內部結構是由核心部分和一系列的功能模塊所組成。這樣劃分是為了使得每個模塊的功能相對簡單,便於開發,同時也便於對系統進行功能擴展。Nginx 的模塊是互相獨立的,低耦合高內聚。
相信通過本文的學習,你應該會對 Nginx 有一個更加全面的認識。