【全網瘋傳】Nginx配置終極指南:從入門到高併發最佳化,流量翻倍實戰攻略

連結:https://www.cnblogs.com/librarookie/p/18773209

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 <name_1> [<name_2> ...] ||     | 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 <connections> #對上游服務啟用長連線,限制每個 worker 子程序與上游伺服器空閒長連線的最大數量。
  • • keepalive_requests <number> #一個長連線最多請求 HTTP 的個數(預設100);:單個長連線可以處理的最多 HTTP 請求個數。
  • • keepalive_timeout <time> #空閒情形下,一個長連線的超時時長;空閒長連線的最長保持時間(預設60s)。
  • • hash #雜湊負載均衡演算法;
  • • ip_hash #客戶端 ip 繫結策略:依據 IP 進行雜湊計算,使來自同一個 ip 的請求永遠只分配一臺伺服器。
  • • least_conn #最少連線數演算法:將請求優先分配給壓力較小的伺服器。
  • • least_time #最短響應時間演算法:優先分配給響應時間最短的伺服器。
  • • random #隨機負載均衡演算法,random 還支援兩種可選的負載均衡模式如下:
    1. 1. random two:從後端伺服器列表中,隨機選擇兩個伺服器,然後根據配置的權重(weight)選擇其中一個。
    2. 2. random two least_conn:從後端伺服器列表中,隨機選擇兩個伺服器,然後選擇其中連線數較少的伺服器。(結合了隨機性和最少連線數的優點)
  • • server <address> [parameters] #定義上游伺服器地址,parameters 可選值:
    1. 1. weight=<number> #權重值,預設為1;
    2. 2. max_conns=<number> #上游伺服器的最大併發連線數;
    3. 3. fail_timeout=<time> #伺服器不可用的判定時間;
    4. 4. max_fails=<numer> #伺服器不可用的檢查次數;
    5. 5. backup #備份伺服器,僅當其他伺服器都不可用時才會啟用;
    6. 6. down #標記伺服器長期不可用,離線維護;
點此檢視:負載均衡演示

1.3.6 return

停止處理請求,直接返回響應碼或重定向到其他 URL ;執行 return 指令後, location 中後續指令將不會被執行。
|     |     || --- | --- ||     | #語法: ||     | #return code [text]; ||     | #return code URL; ||     | #return URL; ||     |     ||     | #例如: ||     | location / { ||     | return 404;     #直接返回狀態碼 ||     | }   ||     |     ||     | location / { ||     | return 404 "pages not found";   #返回狀態碼 + 一段文字 ||     | }   ||     |     ||     | location / { ||     | return 302 /bbs;   #返回狀態碼 + 重定向地址 ||     | }   ||     |     ||     | location / { ||     | return https://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. 1. 客戶端(瀏覽器)訪問 https://www.baidu.com 百度網站;
  2. 2. 百度伺服器返回 HTTPS 使用的 CA 證書;
  3. 3. 瀏覽器驗證 CA 證書是否為合法證書;
  4. 4. 驗證透過,證書合法,生成一串隨機數並使用公鑰(證書中提供的)進行加密;
  5. 5. 傳送公鑰加密後的隨機數給百度伺服器;
  6. 6. 百度伺服器拿到密文,透過私鑰進行解密,獲取到隨機數(公鑰加密,私鑰解密,反之也可以);
  7. 7. 百度伺服器把要傳送給瀏覽器的內容,使用隨機數進行加密後傳輸給瀏覽器;
  8. 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. 1. 啟動一個 Nginx 伺服器,將 server_name 設定為 fe.server.com
  2. 2. 設定相應的 location 以攔截前端需要跨域的請求
  3. 3. 最後將請求代理回 dev.server.com
如下面的配置:
|     |     || --- | --- ||     | server { ||     | listen 80; ||     | server_name fe.server.com; ||     | location / { ||     | proxy_pass http://dev.server.com; ||     | }   ||     | }   |
這樣可以完美繞過瀏覽器的同源策略:
  1. 1. fe.server.com 訪問 Nginx 的 fe.server.com 屬於同源訪問,
  2. 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. 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. 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. 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. 1. 找到 /images 的 location ,然後重寫 URL 為 fe.lion.club/pics/1.jpg
    2. 2. 找到 /pics 的 location ,繼續重寫 URL 為 fe.lion.club/photos/1.jpg
    3. 3. 找到 /photos 的 location 後,去 html/photos 目錄下尋找 1.jpg 靜態資源。

負載均衡演示

配置負載均衡主要是要使用 upstream 指令。
我們把 121.42.11.34 伺服器作為上游伺服器,做如下配置:
|     |     || --- | --- ||     | 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'; ||     | }   ||     | }   |
把 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 { ||     | zone test 10M;    #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. 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. 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 ||     | <h1> 121.42.11.34 proxy html </h1> ||     | 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; ||     | }   ||     | }   |
訪問分析
  • • 當訪問 <www.nginx-test.com> 時,都可以被匹配上,因此選擇優先順序最高的“完全匹配”;
  • • 當訪問 <mail.nginx-test.com> 時,會進行“左匹配”;
  • • 當訪問 <doc.nginx-test.com> 時,會進行“左匹配”;
  • • 當訪問 <www.nginx-test.org> 時,會進行“右匹配”;
  • • 當訪問 <www.nginx-test.cn> 時,會進行“右匹配”;
  • • 當訪問 <fe.nginx-test.club> 時,會進行“正則匹配”;

內建變數例項演示

|     |     || --- | --- ||     | 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 瀏覽器會預設為我們下載一個檔案,下面展示的就是下載的檔案內容:
|     |     || --- | --- ||     | 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 |
Via
  • • https://www.cnblogs.com/ratelcloud/p/18595015
  • • https://www.cnblogs.com/lywJ/p/10710361.html
END
想要學習Linux系統的讀者可以點選"閱讀原文"按鈕來了解書籍《Linux就該這麼學》,同時也非常適合專業的運維人員閱讀,成為輔助您工作的高價值工具書!

相關文章