Nginx 配置與實戰
Nginx 是開源、高性能、高可靠的 Web 和反向代理服務器,而且支持熱部署,幾乎可以做到 7 * 24 小時不間斷運行,即使運行幾個月也不需要重新啟動,還能在不間斷服務的情況下對軟件版本進行熱更新。性能是 Nginx 最重要的考量,其占用內存少、并發能力強、能支持高達 5w 個并發連接數,最重要的是, Nginx 是免費的并可以商業化,配置使用也比較簡單。
Nginx特點:
? 高并發、高性能;
? 模塊化架構使得它的擴展性非常好;
? 異步非阻塞的事件驅動模型這點和 Node.js 相似;
? 相對于其它服務器來說它可以連續幾個月甚至更長而不需要重啟服務器使得它具有高可靠性;
? 熱部署、平滑升級;
? 完全開源,生態繁榮;
一、配置(nginx.conf)
nginx.conf 配置文件的語法規則:
? 配置文件由指令與指令塊構成;
? 每條指令以;分號結尾,指令與參數間以空格符號分隔;
? 指令塊以{}大括號將多條指令組織在一起;
?include語句允許組合多個配置文件以提升可維護性;
? 通過#符號添加注釋,提高可讀性;
? 通過$符號使用變量;
? 部分指令的參數支持正則表達式,例如常用的 location 指令.
Nginx 的典型配置示例:
202503112016964
? main 全局配置,對全局生效;
? events 配置影響 Nginx 服務器與用戶的網絡連接;
? http 配置代理,緩存,日志定義等絕大多數功能和第三方模塊的配置;
? server 配置虛擬主機的相關參數,一個 http 塊中可以有多個 server 塊;
? location 用于配置匹配的 uri ;
? upstream 配置后端服務器具體地址,負載均衡配置不可或缺的部分;
| | | | --- | --- | | |#1. main段配置信息 | | | user nginx; #運行用戶,默認即是nginx,可以不進行設置 | | | worker_processes auto; #Nginx 進程數,一般設置為和 CPU 核數一樣 | | | error_log /var/log/nginx/error.log warn; #Nginx 的錯誤日志存放目錄 | | | pid /var/run/nginx.pid; #Nginx 服務啟動時的 pid 存放位置 | | | | | |#2. events段配置信息 | | | events { | | | use epoll; #使用epoll的I/O模型(缺省會自動選擇一個最適合你操作系統的) | | | worker_connections 1024; #每個進程允許最大并發數 | | | } | | | | | |#3. http段配置信息 | | |#配置使用最頻繁的部分,代理、緩存、日志定義等絕大多數功能和第三方模塊的配置都在這里設置 | | | 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; #減少網絡報文段的數量 | | | tcp_nodelay on; | | | keepalive_timeout 65; #保持連接的時間,也叫超時時間,單位秒 | | | types_hash_max_size 2048; | | | | | | include /etc/nginx/mime.types; #文件擴展名與類型映射表 | | | default_type application/octet-stream; #默認文件類型 | | | | | |#4. server段配置信息 | | | server { | | | listen 80; #配置監聽的端口 | | | server_name localhost; #配置的域名 | | | | | |#5. location段配置信息 | | | location / { | | | root /usr/share/nginx/html; #網站根目錄 | | | 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; #同上 | | | } | | | | | |#加載子配置項 | | | include /etc/nginx/conf.d/*.conf; | | | } |
1.1 內置變量
nginx 常用的內置全局變量,你可以在配置中隨意使用,點此查看效果:內置變量實例演示
變量 | 說明 |
$args | 請求中的參數,例: baidu.com/?a=1&b=1 中的a和b |
$content_length | HTTP 請求信息里的"Content-Length" |
$content_type | HTTP 請求信息里的"Content-Type" |
$document_root | nginx 虛擬主機配置文件中的 root 參數對應的值 |
$document_uri | 當前請求中不包含指令的 URI |
$host | 主機頭,也就是域名 |
$http_user_agent | 客戶端的詳細信息,也就是瀏覽器的標識 |
$http_cookie | 客戶端的 cookie 信息 |
$limit_rate | 如果 nginx服務器使用limit_rate 配置了顯示網絡速率,則會顯示,如果沒有設置,則顯示0 |
$remote_addr | 客戶端的公網ip |
$remote_user | 如果 nginx有配置認證,該變量代表客戶端認證的用戶名 |
$request_body_file | 做反向代理時發給后端服務器的本地資源的名稱 |
$request_method | 請求資源的方式,GET /PUT /DELETE等 |
$request_filename | 當前請求的資源文件的路徑名稱 |
$request_uri | 請求的鏈接,包括args |
$scheme | 請求的協議,如ftp, http, https |
$server_addr | 服務器IP地址 |
$server_name | 服務器的主機名 |
$server_port | 服務器的端口號 |
1.2 全局配置
1.2.1 main 段核心參數
| | | | --- | --- | | |#1. user: 指定運行 Nginx 的 woker 子進程的屬主和屬組,其中組可以不指定。 | | |#語法:user USERNAME [GROUP] | | | user nginx lion; #用戶是nginx; 組是lion | | | | | |#2. pid: 指定運行 Nginx master 主進程的 pid 文件存放路徑。 | | | pid /opt/nginx/logs/nginx.pid; #master主進程的的pid存放在nginx.pid的文件 | | | | | |#3. worker_rlimit_nofile_number: 指定worker子進程可以打開的最大文件句柄數。 | | | worker_rlimit_nofile 20480; #可以理解成每個worker子進程的最大連接數量。 | | | | | |#4. worker_rlimit_core: 指定 worker 子進程異常終止后的 core 文件,用于記錄分析問題。 | | | worker_rlimit_core 50M; #存放大小限制 | | | working_directory /opt/nginx/tmp; #存放目錄 | | | | | |#5. worker_processes_number:指定 Nginx 啟動的 worker 子進程數量。 | | | worker_processes 4; #指定具體子進程數量 | | | worker_processes auto; #與當前cpu物理核心數一致 | | | | | |#6. worker_cpu_affinity:將每個 worker 子進程與我們的 cpu 物理核心綁定。 | | | worker_cpu_affinity 0001 0010 0100 1000; #4個物理核心,4個worker子進程 | | | | | |#7. worker_priority: 指定 worker 子進程的 nice 值,以調整運行 Nginx 的優先級,通常設定為負值,以優先調用 Nginx 。 | | | worker_priority -10; #120-10=110,110就是最終的優先級 | | |#Linux 默認進程的優先級值是120,值越小越優先; nice 值范圍為 -20 到 +19 。 | | | | | |#備注:應用的默認優先級值是120加上 nice 值等于它最終的值,這個值越小,優先級越高。 | | | | | |#8. worker_shutdown_timeout: 指定 worker 子進程優雅退出時的超時時間。 | | | worker_shutdown_timeout 5s; | | | | | |#9. timer_resolution: worker 子進程內部使用的計時器精度,調整時間間隔越大,系統調用越少,有利于性能提升;反之,系統調用越多,性能下降。 | | | timer_resolution 100ms; | | |#在 Linux 系統中,用戶需要獲取計時器時需要向操作系統內核發送請求,有請求就必然會有開銷,因此這個間隔越大開銷就越小。 | | | | | |#10. daemon: 指定 Nginx 的運行方式,前臺還是后臺,前臺用于調試,后臺用于生產。 | | | daemon off; #默認是on,后臺運行模式 |
worker_cpu_affinity:將每個 worker 子進程與特定 CPU 物理核心綁定,優勢在于,避免同一個 worker 子進程在不同的 CPU 核心上切換,緩存失效,降低性能。但其并不能真正的避免進程切換。
202503150320694
1.2.2 events 段核心參數
| | | | --- | --- | | |#1. use:Nginx 使用何種事件驅動模型。 | | | use method; #不推薦配置它,讓nginx自己選擇 | | |#method 可選值為:select、poll、kqueue、epoll、/dev/poll、eventport | | | | | |#2. worker_connections:worker 子進程能夠處理的最大并發連接數。 | | | worker_connections 1024; #每個子進程的最大連接數為1024 | | | | | |#3. accept_mutex:是否打開負載均衡互斥鎖。 | | | accept_mutex on; #默認是off關閉的,這里推薦打開 |
1.3 常用配置
配置 | 位置 | 說明 |
worker_processes 8 | 開始 | 工作進程, 通常等于CPU數最或者2倍于CPU |
include filename | 任意 | 用于引入其他文件 |
worker_connections | events | 最大連接數 |
keepalive_timeout | http | 連接超時時間,默認為75s |
gzip on | http | 開啟 gzip 壓縮 |
client_header_buffer_size | http | 設定請求緩沖 |
client_max_body_size | http | 上傳文件的大小限制,默認 1m |
keepalive_requests | server | 單連接請求上限次數 |
listen 80 | server | 監聽 80 端口 |
server_name | server | 監聽地址 |
error_page | server | 定義錯誤提示界面 |
set | server | 定義變量 |
proxy_pass | location | 代理轉發 |
rewrite | location | 重定向 |
return | location | 停止處理請求 |
1.3.1 server_name
指定虛擬主機域名
| | | | --- | --- | | |#語法:server_name[ ...] | | | server_name www.nginx.com; |
域名匹配的四種寫法:
? 精確匹配:server_name www.nginx.com
? 左側通配:server_name *.nginx.com
? 右側統配:server_name www.nginx.*
? 正則匹配:server_name ~^www.nginx.*$匹配優先級:精確匹配 > 左側通配符匹配 > 右側通配符匹配 > 正則表達式匹配
點此查看:server_name實例演示
1.3.2 location
| | | | --- | --- | | |#配置 URL路徑 | | | location [ = | ~ | ~* | ^~ ] uri { ... } |
匹配規則(點此查看:location實例演示):
?=精確匹配;
?~正則匹配,區分大小寫;
?~*正則匹配,不區分大小寫;
?^~匹配到即停止搜索; 匹配優先級:=>^~>~>~*>無符號
location 的末尾斜線/
| | | | --- | --- | | |#當訪問 www.nginx-test.com/test 時,location 中的是否有末尾反斜線,結果如下: | | | location /test/ { ... } | | |#末尾帶 / 時,Nginx 只會找 test/index.html 文件。 | | | | | | location /test { ... } | | |#末尾不帶 / 時,Nginx 會先找 test/index.html 文件,沒有再找 test 文件。 | | |##即:先找是否有 test 目錄,有則找 test 目錄下的 index.html ;沒有則會找是否有 test 文件。 |
1.3.3 root 與 alias
root 與 alias 都可以指定靜態資源目錄位置,兩者選其一即可
尋找資源時:root 會將定義路徑與URI疊加,alias 則只取定義路徑
當用戶訪問 http://www.test.com/image/1.png 時,實際在服務器找的路徑是 /opt/nginx/static/image/1.png
? root:指定靜態資源目錄位置,可以寫在 http、server、location 等配置中。
| | | | --- | --- | | |#語法:root path | | | location /image { | | | root /opt/nginx/static; | | | } |
? alias:指定靜態資源目錄位置,只能寫在 location 中,且資源路徑以/結尾。
| | | | --- | --- | | |#語法:root path/ | | | location /image { | | |alias/opt/nginx/static/image/; | | | } |
1.3.4 proxy_pass 代理轉發
用于配置代理服務器,如:正向代理,反向代理(點擊即可查看演示)
| | | | --- | --- | | |#上下文:location、if、limit_except | | | | | |#語法:proxy_pass URL; | | | proxy_pass http://127.0.0.1:8081 | | | proxy_pass http://127.0.0.1:8081/proxy |
URL 參數原則:
? URL 必須以 http 或 https 開頭;
? URL 中可以攜帶變量;
? URL 中是否帶 URI ,會直接影響發往上游請求的 URL ;
在配置代理時,proxy_pass 有末尾 帶和 不帶 / 兩種用法,它們的區別可大了:proxy_pass實例演示
1.3.5 upstream 負載均衡
用于定義上游服務器(指的就是后臺提供的應用服務器)的相關信息。
202503122011275
| | | | --- | --- | | |#上下文:http | | | | | |##語法 | | |#upstream name { | | |# server address [parameters] #定義上游服務器地址。 | | |#} | | | | | |##配置示例 | | | upstream back_end_server { | | |#上游服務器 權重 最大連接數 判定失敗的超時時間 連接失敗數 | | | 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; | | | } |
在 upstream 內可使用的指令:
?zone#定義共享內存,用于跨 worker 子進程;
?keepalive
?keepalive_requests
?keepalive_timeout
?hash#哈希負載均衡算法;
?ip_hash#客戶端 ip 綁定策略:依據 IP 進行哈希計算,使來自同一個 ip 的請求永遠只分配一臺服務器。
?least_conn#最少連接數算法:將請求優先分配給壓力較小的服務器。
?least_time#最短響應時間算法:優先分配給響應時間最短的服務器。
?random#隨機負載均衡算法,random 還支持兩種可選的負載均衡模式如下:
1.random two:從后端服務器列表中,隨機選擇兩個服務器,然后根據配置的權重(weight)選擇其中一個。
2.random two least_conn:從后端服務器列表中,隨機選擇兩個服務器,然后選擇其中連接數較少的服務器。(結合了隨機性和最少連接數的優點)
?server
[parameters]#定義上游服務器地址,parameters 可選值:
1.weight=
2.max_conns=
3.fail_timeout=
4.max_fails=
5.backup#備份服務器,僅當其他服務器都不可用時才會啟用;
6.down#標記服務器長期不可用,離線維護;
點此查看:負載均衡演示
1.3.6 return
停止處理請求,直接返回響應碼或重定向到其他 URL ;執行 return 指令后, location 中后續指令將不會被執行。
| | | | --- | --- | | |#語法: | | |#return code [text]; | | |#return code URL; | | |#return URL; | | | | | |#例如: | | | location / { | | |return404; #直接返回狀態碼 | | | } | | | | | | location / { | | |return404"pages not found"; #返回狀態碼 + 一段文本 | | | } | | | | | | location / { | | |return302 /bbs; #返回狀態碼 + 重定向地址 | | | } | | | | | | location / { | | |returnhttps://www.baidu.com; #返回重定向地址 | | | } |
1.3.7 rewrite
根據指定正則表達式匹配規則,重寫 URL 。
| | | | --- | --- | | |#上下文(標簽):server、location、if | | | | | |#語法:rewrite <正則表達式> <要替換的內容> [flag]; | | | rewirte /images/(.*.jpg)$ /pic/$1; #變量$1 是前面括號(.*.jpg)的反向引用 |
flag可選值的含義:
?last重寫后的 URL 發起新請求,再次進入 server 段,重試 location 的中的匹配;
?break直接使用重寫后的 URL ,不再匹配其它 location 中語句;
?redirect返回 302 臨時重定向;
?permanent返回 301 永久重定向;
點此查看:rewrite實例演示
1.3.8 if
| | | | --- | --- | | |#上下文:server、location | | | | | |#語法:if (condition) { ... } | | |if($http_user_agent~ Chrome) { | | | rewrite /(.*) /browser/$1break; | | | } | | | | | |#實例:當訪問 localhost:8080/images/ 時,會進入 if 判斷里面,并執行 rewrite 命令。 | | | server { | | | listen 8080; | | | server_name localhost; | | | root html; | | | | | | location / { | | |if($uri="/images/") { | | | rewrite (.*) /pics/break; | | | } | | | } | | | } |
condition 判斷條件:
?$variable#僅為變量時,值為空或以0開頭,字符串都會被當做 false 處理;
?=!=#相等或不等;
?~#正則匹配;
?~*#正則匹配,不區分大小寫;
?-f#檢測 文件 存在;
?-d#檢測 目錄 存在;
?-e#檢測 文件、目錄、符號鏈接 等存在;
?-x#檢測文件可以執行;
?!#取反,非;如! ~非正則匹配;或! -f文件不存在
1.3.9 autoindex
用戶請求以 / 結尾時,列出目錄結構,可以用于快速搭建靜態資源下載網站。
202503121927444
autoindex-nginx.conf 配置信息:
| | | | --- | --- | | |#當訪問 fe.lion.com/download/ 時,會把服務器 /opt/source/download/ 路徑下的文件展示出來 | | | server { | | | listen 80; | | | server_name fe.lion-test.club; | | | | | | location /download/ { | | | root /opt/source; | | | | | | autoindex on; #打開 autoindex,可選參數有 on | off | | | autoindex_exact_size on; #修改為off(默認on),以bytes(KB、MB、GB)顯示出?件的確切?? | | | autoindex_format html; #以html的方式進行格式化,可選參數有 html | json | xml | | | autoindex_localtime off; #顯示的?件時間為?件的服務器時間(默認off)。顯示的?件時間為GMT時間 | | | } | | | } |
1.4 HTTPS
在學習如何配置 HTTPS 之前,我們先來簡單回顧下 HTTPS 的工作流程是怎么樣的?它是如何進行加密保證安全的?
1.4.1 HTTPS 工作流程
1. 客戶端(瀏覽器)訪問 https://www.baidu.com 百度網站;
2. 百度服務器返回 HTTPS 使用的 CA 證書;
3. 瀏覽器驗證 CA 證書是否為合法證書;
4. 驗證通過,證書合法,生成一串隨機數并使用公鑰(證書中提供的)進行加密;
5. 發送公鑰加密后的隨機數給百度服務器;
6. 百度服務器拿到密文,通過私鑰進行解密,獲取到隨機數(公鑰加密,私鑰解密,反之也可以);
7. 百度服務器把要發送給瀏覽器的內容,使用隨機數進行加密后傳輸給瀏覽器;
8. 此時瀏覽器可以使用隨機數進行解密,獲取到服務器的真實傳輸內容;
這就是 HTTPS 的基本運作原理,使用對稱加密和非對稱機密配合使用,保證傳輸內容的安全性。
有興趣的可點此查看:《什么是 SSL、TLS 和 HTTPS?》
1.4.2 配置證書
下載證書的壓縮文件,里面有個 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協議版本,默認為后三個,主流版本是[TLSv1.2] | | | | | | location / { | | | root /usr/share/nginx/html; | | | index index.html index.htm; | | | } | | | } |
注意:
? ssl_certificate證書的后綴不固定,目前知道的有有:.cer、.pem、.crt ;
? ssl_certificate_key的文件的后綴是固定的為.key
1.5 CORS 跨域配置
CORS(Cross-Origin Resource Sharing,跨源資源共享)是一種瀏覽器機制,允許網頁從不同的域(源)請求資源。它通過使用額外的 HTTP 頭來告訴瀏覽器,允許某個源(協議 + 域名 + 端口)訪問資源,即使這些資源來自不同的源。
1.5.1 跨域的定義
同源策略限制了從同一個源加載的文檔或腳本如何與來自另一個源的資源進行交互。
這是一個用于隔離潛在惡意文件的重要安全機制。通常不允許不同源間的讀操作。
1.5.2 同源的定義
如果兩個頁面的協議,域名和端口都相同,則兩個頁面具有相同的源。
與 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 不同源:主機不同
不同源會有如下限制:
? Web 數據層面:同源策略限制了不同源的站點讀取當前站點的 Cookie 、 IndexDB 、 LocalStorage 等數據。
? DOM 層面:同源策略限制了來自不同源的 JavaScript 腳本對當前 DOM 對象讀和寫的操作。
? 網絡層面:同源策略限制了通過 XMLHttpRequest 等方式將站點的數據發送給不同源的站點。
1.5.3 Nginx 跨域方案
例如:
? 前端服務的域名為: fe.server.com
? 后端服務的域名為: dev.server.com
現在我在 fe.server.com 對 dev.server.com 發起請求一定會出現跨域。
1. 啟動一個 Nginx 服務器,將 server_name 設置為 fe.server.com
2. 設置相應的 location 以攔截前端需要跨域的請求
3. 最后將請求代理回 dev.server.com
如下面的配置:
| | | | --- | --- | | | server { | | | listen 80; | | | server_name fe.server.com; | | | location / { | | | proxy_pass http://dev.server.com; | | | } | | | } |
這樣可以完美繞過瀏覽器的同源策略:
1. fe.server.com 訪問 Nginx 的 fe.server.com 屬于同源訪問,
2. 而 Nginx 對服務端轉發的請求不會觸發瀏覽器的同源策略。
1.6 gzip 壓縮
GZIP 是規定的三種標準 HTTP 壓縮格式之一。目前絕大多數的網站都在使用 GZIP 傳輸 HTML、CSS、JavaScript 等資源文件。
對于文本文件, GZiP 的效果非常明顯,開啟后傳輸所需流量大約會降至 1/4~1/3 。
啟用 gzip 同時需要客戶端和服務端的支持,然而并不是每個瀏覽器都支持 gzip 的。
可以通過請求頭中的 Accept-Encoding 來標識對壓縮的支持,如圖:
202503150232712
如果客戶端支持 gzip 的解析,那么只要服務端能夠返回 gzip 的文件就可以啟用 gzip 了,
可以通過 Nginx 的配置來讓服務端支持 gzip 。下面的 respone 中 content-encoding:gzip ,指服務端開啟了 gzip 的壓縮方式。
202503150233152
| | | | --- | --- | | |#是否開啟gzip | | | gzip on; #默認 off | | | | | |#采用 gzip 壓縮的 MIME 文件類型,其中 text/html 被系統強制啟用; | | | gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; | | | | | |#---- 以上兩個參數開啟就可以支持Gzip壓縮了 ----# | | | | | |#該模塊啟用后,Nginx 首先檢查是否存在請求靜態文件的 gz 結尾的文件,如果有則直接返回該 .gz 文件內容; | | | gzip_static on; #默認 off | | | | | |#nginx做為反向代理時啟用,用于設置"啟用或禁用"從代理服務器上收到相應內容 gzip 壓縮; | | | gzip_proxied any; #默認 off | | | | | |#用于在響應消息頭中添加 Vary:Accept-Encoding,使代理服務器根據請求頭中的 Accept-Encoding 識別是否啟用 gzip 壓縮; | | | gzip_vary on; | | | | | |#gzip 壓縮比,壓縮級別是 1-9,級別越高壓縮率越大,壓縮時間越長;1 壓縮級別最低,9 最高,建議 4-6; | | | gzip_comp_level 6; | | | | | |#獲取多少內存,用于緩存壓縮結果 | | | gzip_buffers 16 8k; #16 8k 表示以 8k*16 為單位獲得 | | | | | |#允許壓縮的頁面最小字節數,頁面字節數從header頭中的 Content-Length 中進行獲取。 | | |#建議設置成大于 1k 的字節數,小于 1k 可能會越壓越大;(默認值是 0,不管頁面多大都壓縮) | | | gzip_min_length 1k; | | | | | |#啟用 gzip 所需的 HTTP 最低版本; | | | gzip_http_version 1.1; #默認 1.1 |
1.7 Nginx 配置黑/白名單
Nginx 利用 deny 和 allow 指令來實現黑 /白名單的配置,利用黑白名單進行安全配置。
| | | | --- | --- | | |#上下文:http、server、location | | | | | |#語法 | | | allow address | CIDR | all; #允許訪問 | | | deny address | CIDR | all; #禁止訪問 |
參數說明:
? address:具體的ip地址。
? CIDR:ip加掩碼形式地址。
? all:所有ip地址。
例子:
1. 黑名單: 配置禁止的ip訪問,允許其他所有的地址訪問。
| | | | --- | --- | | | deny 192.168.1.234 | | | deny 192.168.1.235 | | | deny 192.168.1.236 | | | | | | allow all; |在這個配置下,234、235和236的ip訪問不了服務器,會顯示403 Forbidden,而其他ip都可以訪問。
2. 白名單: 配置允許的ip訪問,禁止其他所有的地址訪問。
| | | | --- | --- | | | allow 192.168.1.234 | | | allow 192.168.1.235 | | | allow 192.168.1.236 | | | | | | deny all; |在這個配置下,234、235和236的ip可以訪問服務器,而其他所有ip都不允許訪問,顯示403 Forbidden。
3. 配置禁止訪問文件或文件夾
| | | | --- | --- | | | location ^~ /project/deny.txt {#明確請求是對其起作用的; | | |alias /webroot/proj/; #解析到 /webroot/proj 目錄 | | | deny all; #屏蔽任何來源 | | | } |
也可以把 deny all 改換成 return 404,這樣將返回 404 而不是 403 Forbidden,更有“欺騙性”。
1.8 緩存配置
緩存可以非常有效的提升性能,因此不論是客戶端(瀏覽器),還是代理服務器( Nginx ),乃至上游服務器都多少會涉及到緩存。可見緩存在每個環節都是非常重要的。
存儲一些之前被訪問過、而且可能將要被再次訪問的資源,使用戶可以直接從代理服務器獲得,從而減少上游服務器的壓力,加快整個訪問速度。
下面讓我們來學習 Nginx 中如何設置緩存策略。
1.8.1 緩存文件設置
| | | | --- | --- | | |#上下文:http | | | | | |#### proxy_cache_path | | |#設置緩存文件的存放路徑。 | | | proxy_cache_path path [level=levels] ... #默認值:proxy_cache off; |
參數含義:
? path #緩存文件的存放路徑;
? level #path的目錄層級;
? keys_zone #設置共享內存;
? inactive #在指定時間內沒有被訪問,緩存會被清理,默認10分鐘;
1.8.2 緩存條件設置
| | | | --- | --- | | |#上下文:http、server、location | | | | | |#### proxy_no_cache | | |#定義相應保存到緩存的條件,如果字符串參數的至少一個值不為空且不等于 “0”,則將不保存該響應到緩存。 | | |#語法:proxy_no_cache string; | | | proxy_no_cache$http_pragma$http_authorization; | | | | | |#### proxy_cache_bypass | | |#定義條件,在該條件下將不會從緩存中獲取響應。 | | |#語法:proxy_cache_bypass string; | | | proxy_cache_bypass$http_pragma$http_authorization; |
1.8.3 緩存參數配置
| | | | --- | --- | | |#上下文:http、server、location | | | | | |#### proxy_cache | | |#緩存開關 | | | proxy_cache zone | off ; # zone 是共享內存的名稱(默認值:off;) | | | | | |#### proxy_cache_valid | | |#配置什么狀態碼可以被緩存,以及緩存時長。 | | |#語法:proxy_cache_valid [code...] time; | | | proxy_cache_valid 200 304 2m; #說明對于狀態為200和304的緩存文件的緩存時間是2分鐘 | | | | | |#### proxy_cache_key | | |#設置緩存文件的 key | | | proxy_cache_key #默認值 $scheme$proxy_host$request_uri; |
upstream_cache_status變量,設置在響應頭信息中,在調試中非常有用,它存儲了緩存是否命中的信息,如下:
?MISS: #未命中緩存
?HIT:: #命中緩存
?EXPIRED: #緩存過期
?STALE: #命中了陳舊緩存
?REVALIDDATED: #Nginx驗證陳舊緩存依然有效
?UPDATING: #內容陳舊,但正在更新
?BYPASS: #響應從原始服務器獲取
1.8.4 緩存配置實例
上游服務器:121.42.11.34 ,配置如下:
| | | | --- | --- | | | 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 ,配置如下:
| | | | --- | --- | | |# 緩存文件設置 | | | 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; #設置緩存內存,上面配置中已經定義好的 | | | proxy_cache_valid 200 5m; #緩存狀態為200的請求,緩存時長為5分鐘 | | | proxy_cache_key$request_uri; #緩存文件的key為請求的URI | | | add_header Nginx-Cache-Status$upstream_cache_status #把緩存狀態設置為頭部信息,響應給客戶端 | | | proxy_pass http://cache_server; #代理轉發 | | | } | | | } |
緩存就是這樣配置,我們可以在 /etc/nginx/cache_temp 路徑下找到相應的緩存文件。
對于一些實時性要求非常高的頁面或數據來說,就不應該去設置緩存,下面來看看如何配置不緩存的內容。
添加過濾條件,過濾請求不緩存:
| | | | --- | --- | | |# 緩存文件設置 | | | 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; | | |# 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; #設置緩存內存 | | | proxy_cache_valid 200 5m; #緩存狀態為200的請求,緩存時長為5分鐘 | | | proxy_cache_key$request_uri; #緩存文件的key為請求的URI | | | add_header Nginx-Cache-Status$upstream_cache_status #把緩存狀態設置為頭部信息,響應給客戶端 | | | proxy_pass http://cache_server; #代理轉發 | | | } | | | } |
二、栗子
rewrite實例演示
| | | | --- | --- | | | server{ | | | listen 80; | | | server_name fe.lion.club; #要在本地hosts文件進行配置 | | | root html; | | | location /search { | | | rewrite ^/(.*) https://www.baidu.com redirect; #返回 302 并臨時重定向到百度 | | | } | | | | | | 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 時:
1. 找到 /images 的 location ,然后重寫 URL 為 fe.lion.club/pics/1.jpg
2. 找到 /pics 的 location ,繼續重寫 URL 為 fe.lion.club/photos/1.jpg
3. 找到 /photos 的 location 后,去 html/photos 目錄下尋找 1.jpg 靜態資源。
負載均衡演示
配置負載均衡主要是要使用 upstream 指令。
我們把 121.42.11.34 服務器作為上游服務器,做如下配置:
| | | | --- | --- | | | server { | | | listen 8020; | | | location / { | | |return200'return 8020 '; | | | } | | | } | | | | | | server { | | | listen 8030; | | | location / { | | |return200'return 8030 '; | | | } | | | } | | | | | | server { | | | listen 8040; | | | location / { | | |return200'return 8040 '; | | | } | | | } |
把 121.5.180.193 服務器作為代理服務器,做如下配置:
| | | | --- | --- | | |#1. 配置本地 hosts | | |sudotee-a /etc/hosts <<-EOF | | ? ? | 121.5.180.193 balance.lion.club | | ? ? | EOF?| | ? ? | ? ? | | ? ? |?#2. 代理配置 | | ? ? |?#/etc/nginx/conf.d/demo-nginx.conf | | ? ? |?tee?/etc/nginx/conf.d/demo-nginx.conf <<-EOF | | ? ? | 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 和域名的映射關系。
在客戶端機器執行 curl http://balance.lion.club/balance/ 命令:
202503141712990
如圖所示:負載均衡的配置已經生效了,通過簡單的"輪詢策略"進行上游服務器分發,每次給我們分發的上游服務器都不一樣。
接下來,我們再來了解下 Nginx 的其它分發策略:hash、ip_hash 和 least_conn最少連接數算法。
hash、ip_hash 和 least_conn
| | | | --- | --- | | |#### hash 算法 | | |#通過指定關鍵字作為 hash-key ,基于 hash 算法映射到特定的上游服務器中。 | | |#關鍵字可以包含有變量、字符串。 | | | upstream demo_server { | | |#表示使用 request_uri變量作為 hash的 key值,只要訪問的 URI 保持不變,就會一直分發給同一臺服務器。 | | |hash$request_uri; | | | server 121.42.11.34:8020; | | | server 121.42.11.34:8030; | | | server 121.42.11.34:8040; | | | } | | | | | |#### ip_hash 算法(可以有效解決后臺服務器 session 保持的問題) | | |#根據客戶端的請求 ip進行判斷,只要 ip地址不變,就永遠分配到同一臺主機。 | | | upstream demo_server { | | | ip_hash; | | | server 121.42.11.34:8020; | | | server 121.42.11.34:8030; | | | server 121.42.11.34:8040; | | | } | | | | | |#### least_conn最少連接數算法 | | |#各個 worker子進程通過讀取共享內存的數據,獲取后端服務器的信息來挑選一臺,當前已建立“連接數最少”的服務器進行分配請求。 | | | upstream demo_server { | | | zonetest10M; #zone可以設置共享內存空間的名字和大小 | | | 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; | | | } | | | } |
配置本地 hosts
| | | | --- | --- | | |sudotee-a /etc/hosts <<-EOF | | ? ? | 121.5.180.193 balance.lion.club | | ? ? | EOF?|
proxy_pass實例演示
用戶請求URL:/bbs/abc/test.html
1. 不帶 / 的用法:
| | | | --- | --- | | |#不帶 / 意味著 Nginx 不會修改用戶 URL ,而是直接透傳給上游的應用服務器; | | | location /bbs/ { | | | proxy_pass http://127.0.0.1:8080; | | | } |分析:與 alias 相似
? 請求到達 Nginx 的 URL:/bbs/abc/test.html
? 請求到達上游應用服務器的 URL:/bbs/abc/test.html
? alias值=url: alias /$PATH/bbs/abc/
2. 帶 / 的用法:
| | | | --- | --- | | |#帶 / 意味著 Nginx 會修改用戶 URL ,修改方法是將 location 的參數從用戶 URL 中刪除; | | | location /bbs/ { | | | proxy_pass http://127.0.0.1:8080/; | | | } |分析:與 root 相似,沒有拼接上 location
? 請求到達 Nginx 的 URL: /bbs/abc/test.html
? 請求到達上游應用服務器的URL: /abc/test.html
? root值=url-location:root /$PATH/abc/
正向代理
如果把局域網外的Internet想象成一個巨大的資源庫,則局域網中的客戶端要訪問Internet,則需要通過代理服務器來訪問,這種代理服務就稱為正向代理。
Nginx正向代理涉及到的指令較少,只是對用戶的訪問進行一個轉發,不做其他處理。配置如下:
| | | | --- | --- | | | server { | | | resolver 192.168.1.1; #指定DNS服務器IP地址 | | | listen 8080; | | | location / { | | |#設定代理服務器的協議和地址 | | | proxy_pass http://$http_host$request_uri; | | | } | | | } |
其中:
? resolver 必須的,表示DNS服務器;
? listen 指定監聽端口號(不指定默認監聽 80 端口);
? location 表示匹配用戶訪問的資源,并作進一步轉交和處理,可用正則表達式匹配;
? proxy_pass 表示需要代理的地址;
? $http_host 表示用戶訪問資源的主機部分;
? $request_uri 表示用戶訪問資源的URI部分。
如:http://nginx.org/download/nginx-1.6.3.tar.gz,則$http_host=nginx.org,$request_uri=/download/nginx-1.6.3.tar.gz
反向代理
為了演示更加接近實際,準備了兩臺云服務器,分別是:121.42.11.34 與 121.5.180.193
我們把 121.42.11.34 服務器作為上游服務器,做如下配置:
| | | | --- | --- | | |#1. 頁面 index.html | | |tee/usr/share/nginx/html/proxy/index.html <<-EOF | | ? ? |121.42.11.34 proxy html
| | | EOF| | | | | |#2. 代理配置 | | |#/etc/nginx/conf.d/proxy-nginx.conf | | |tee/etc/nginx/conf.d/proxy-nginx.conf <<-EOF | | ? ? | server{ | | ? ? | listen 8080; | | ? ? | server_name localhost; | | ? ? | ? ? | | ? ? | location /proxy/ { | | ? ? | root /usr/share/nginx/html/proxy; | | ? ? | index index.html; | | ? ? | } ? | | ? ? | } ? | | ? ? | EOF?| | ? ? | ? ? | | ? ? |?#3. 配置完成后重新加載配置文件 | | ? ? | nginx -s reload |
把 121.5.180.193 服務器作為代理服務器,做如下配置:
| | | | --- | --- | | |#1. 配置本地 hosts | | |sudotee-a /etc/hosts <<-EOF | | ? ? | 121.5.180.193 proxy.lion.club | | ? ? | EOF?| | ? ? | ? ? | | ? ? |?#2. 代理配置 | | ? ? |?#/etc/nginx/conf.d/proxy-nginx.conf | | ? ? |?tee?/etc/nginx/conf.d/proxy-nginx.conf <<-EOF | | ? ? | 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; | | ? ? | } ? | | ? ? | } ? | | ? ? | EOF?|
分析:
? 當訪問 proxy.lion.club/proxy 時,通過 upstream 的配置找到 121.42.11.34:8080 ;
? 因此訪問地址變為 http://121.42.11.34:8080/proxy ;
? 連接到 121.42.11.34 服務器,找到 8080 端口提供的 server ;
? 通過 server 找到 /usr/share/nginx/html/proxy/index.html 資源,最終展示出來。
202503141509395
location實例演示
| | | | --- | --- | | | 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; | | | } | | | } |
server_name實例演示
因為虛擬域名進行測試,因此需要配置本地 DNS 解析,如果使用阿里云上購買的域名,則需要在阿里云上設置好域名解析。
| | | | --- | --- | | |#配置本地 DNS 解析 hosts | | | 121.42.11.34 www.nginx-test.com | | | 121.42.11.34 www.nginx-test.org | | | 121.42.11.34 www.nginx-test.cn | | | 121.42.11.34 mail.nginx-test.com | | | 121.42.11.34 doc.nginx-test.com | | | 121.42.11.34 fe.nginx-test.club |
配置 nginx.conf 的 server 配置
| | | | --- | --- | | |# 完全匹配 | | | server { | | | listen 80; | | | server_name www.nginx-test.com; | | | root /usr/share/nginx/html/nginx-test/all-match/; | | | location / { | | | index index.html; | | | } | | | } | | | | | |# 左匹配 | | | 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 www.nginx-test.*; | | | root /usr/share/nginx/html/nginx-test/right-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 8081; | | | server_name var.lion-test.club; | | | root /usr/share/nginx/html; | | | location / { | | |return200" | | | 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 瀏覽器會默認為我們下載一個文件,下面展示的就是下載的文件內容:
| | | | --- | --- | | | 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 |
鏈接:https://www.cnblogs.com/librarookie/p/18773209
-
Web
+關注
關注
2文章
1285瀏覽量
70944 -
服務器
+關注
關注
13文章
9728瀏覽量
87439 -
nginx
+關注
關注
0文章
167瀏覽量
12522
原文標題:【全網瘋傳】Nginx配置終極指南:從入門到高并發優化,流量翻倍實戰攻略
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
nginx錯誤頁面配置
主要學習下nginx的安裝配置
運行nginx所需的最低配置
Nginx常用的配置和基本功能講解
Nginx的特點和作用 Nginx常用命令和核心配置

Nginx常用配置與命令

評論