Nginx-2 詳解處理 Http 請求

Nginx-2 詳解處理 Http 請求

Nginx 作為當今最流行的開源 Web 服務器之一,以其高性能、高穩定性和豐富的功能而聞名。在處理 HTTP請求 的過程中,Nginx 采用了模塊化的設計,將整個請求處理流程劃分為若干個階段,每個階段都可以由特定的模塊來處理。這種設計不僅使得 Nginx 具有極高的靈活性和可擴展性,而且也方便了開發者對 Nginx 進行定制和優化。

Nginx 在與客戶端建立連接(三次握手)后通過事件驅動模塊獲取 Http 請求,解析 header 頭部并進行處理,接下來的處理可以大致分為以下 11 階段,每個階段都會有一些模塊和配置項進行處理,需要關注的是每個模塊可以發揮什么作用,有哪些配置項。

image-20250613114549375

而每一個階段中的也可能有多個模塊可以對其發揮作用,這些模塊之間也是有順序的

image-20250613114728929

具體的處理順序可以去 nginx-1.28.0/objs/ngx_modules.c 中查看,該文件中 ngx_module_names 字段標識了模塊的處理順序,正常為由下向上執行,某些特殊指令可以跳轉到其他模塊

char *ngx_module_names[] = {"ngx_core_module","ngx_errlog_module","ngx_conf_module","ngx_regex_module","ngx_events_module","ngx_event_core_module","ngx_epoll_module","ngx_http_module","ngx_http_core_module","ngx_http_log_module","ngx_http_upstream_module","ngx_http_static_module","ngx_http_autoindex_module","ngx_http_index_module","ngx_http_mirror_module","ngx_http_try_files_module","ngx_http_auth_basic_module","ngx_http_access_module","ngx_http_limit_conn_module","ngx_http_limit_req_module","ngx_http_realip_module","ngx_http_geo_module","ngx_http_map_module","ngx_http_split_clients_module","ngx_http_referer_module","ngx_http_rewrite_module","ngx_http_proxy_module","ngx_http_fastcgi_module","ngx_http_uwsgi_module",......
}

1、POST_READ

該階段為接受到完整的 HTTP 頭部后,讀取請求內容階段,nginx 讀取并解析完請求頭之后就立即開始執行

該階段經常用到 realip 模塊,可以獲取到一些原始的值,用于做日志分析、限流等使用

我們知道一個請求從發出到 nginx 接收,中間可能經過了多臺服務器,為了獲取到這個原始 IP,通常會使用兩個特定的HTTP頭部字段:X-Forwarded-ForX-Real-IP

  • X-Forwarded-For:用于傳遞客戶端請求經過的所有代理服務器的 IP 地址。這個頭部通常包含一個或多個 IP地址,它們按照請求經過代理的順序排列。如果請求直接發送到服務器,則此頭部可能不存在或只包含客戶端的 IP 地址。
  • X-Real-IP:記錄客戶端的真實 IP 地址,它只包含一個 IP 地址。這個頭部字段由第一個代理服務器設置,并且在請求穿越后續代理時不會被更改,因此它代表了客戶端的原始 IP 地址。

realip 模塊

  • 默認不會編譯,需要編譯時使用 --with-http_realip_module 加入
  • 配置項
    • set_real_ip_from:此指令用于定義信任的代理服務器。只有來自這些服務器的 X-Real-IPX-Forwarded-For 頭部字段才會被 Nginx 接受和處理。
    • real_ip_header:通過這個指令,可以指定 Nginx 應該使用 X-Real-IP 還是 X-Forwarded-For 頭部來確定客戶端的真實 IP 地址。
    • realip_recursive:默認關閉,指示 realip 模塊是否已經遞歸地處理了 X-Forwarded-For 頭部字段。
  • 重要變量
    • http_x_real_ip:包含X-Real-IP頭部的值,即客戶端的真實IP地址。如果該頭部不存在,則變量為空
    • remote_addr:默認情況下,這個變量包含服務器接收到的客戶端 IP 地址。當realip模塊啟用并正確配置后,它會被設置為客戶端的真實 IP 地址。
    • http_x_forwarded_for:包含X-Forwarded-For頭部的值,這是一個 IP 地址列表,記錄了客戶端以及所有中間代理服務器的IP。

實戰:

server {listen 9090;location / {proxy_pass http://127.0.0.1:9091;  # 將請求轉發到 server 2proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  # 本機 IP 加入proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-Proto $scheme;}
}server {listen 9091;# 在 server 2 中配置 realip 模塊set_real_ip_from 127.0.0.1;        # 允許來自本地的 IP 地址作為反向代理real_ip_header X-Forwarded-For;    # 使用 X-Forwarded-For 頭部獲取真實 IPreal_ip_recursive on;              # 如果有多個代理,遞歸獲取真實 IPlocation / {access_log /home/nginx/nginx/logs/access_realip.log;# 測試輸出真實 IPreturn 200 "\nClient real ip: $remote_addr, X-Forwarded-For: $http_x_forwarded_for\n";}
}

簡單解釋一下:

在本機 nginx 啟動兩個端口 9090 和 9091,9090 在收到請求后會模擬代理服務器轉發給 9091,9091 認為本機 ip 是可信的(可以這么理解:如果這個 ip 是可信的,它給我說它收到了一個來自 ** 的請求我才相信,否則我就認為和我三次握手的那個 ip 才是真正的請求 ip )

測試:

[root@VM-16-11-centos ~]# curl -H 'X-Forwarded-For: 1.1.1.1, 2.2.2.2' 123.207.214.107:9090Client real ip: 123.207.214.107, X-Forwarded-For: 1.1.1.1, 2.2.2.2, 123.207.214.107

修改 set_real_ip_from 的值為 127.0.0.2 再測試

[root@VM-16-11-centos ~]# curl -H 'X-Forwarded-For: 1.1.1.1, 2.2.2.2' 123.207.214.107:9090Client real ip: 127.0.0.1, X-Forwarded-For: 1.1.1.1, 2.2.2.2, 123.207.214.107

原因是: 127.0.0.1 被認為不可信,所以雖然 X-Forwarded-For 中最后一個 ip 是 123.207.214.107,但 9091 發現與自己通信的其實是本機的 9090,認為真實 ip 就是 127.0.0.1

2、SERVER_REWRITE

在 uri 與 location 匹配之前修改請求的 URI(重定向),在 server 塊中的請求地址重寫階段

由于該階段在 rewrite 階段前,所以如果這里出現 return 指令,就不會返回 location 中的 return 了

【1】測試 server 下的重寫

server {listen 9092;root html/;# 測試 server 下的重寫 404 但是返回 403 界面error_page 404 /403.html;}
[root@VM-16-11-centos nginx]# cat html/403.html
This is 403!
[root@VM-16-11-centos ~]# curl 123.207.214.107:9092/test.txt
This is 403!

【2】server 下的重寫與 location 中的 return 相比,return 生效

server {listen 9092;root html/;# 測試 server 下的 error_page 和 location 下的 return 生效情況:location 生效error_page 404 /403.html;location / {return 404 "find nothing location!\n";}}
[root@VM-16-11-centos ~]# curl 123.207.214.107:9092/test.txt
find nothing location!

【2】server 下的 return 先于 location 中的 return 返回

server {listen 9092;root html/;# 測試 server 下的 error_page 和 location 下的 return 生效情況:location 生效error_page 404 /403.html;location / {return 404 "find nothing location!\n";}# 測試 server 下的 return 和 location 下的 return 生效: server 中生效return 404 "find nothing server!\n";}
[root@VM-16-11-centos ~]# curl 123.207.214.107:9092/test.txt
find nothing server!

3、FIND_CONFIG

配置查找階段,根據請求 uri 匹配 location 表達式,這個階段不支持 nginx 模塊注冊處理程序,而是由ngx_http_core_module 模塊來完成當前請求與 location 配置快之間的配對工作

location 的匹配規則是僅匹配 URI,忽略參數,有下面三種大的情況:

  • 前綴字符串
    • 常規匹配
    • =:精確匹配
    • ^~:匹配上后則不再進行正則表達式匹配
  • 正則表達式
    • ~:大小寫敏感的正則匹配
    • ~*:大小寫不敏感
  • 用戶內部跳轉的命名 location ,可以通過 error_pagetry_files 等指令進行內部跳轉。
    • @

建議不同業務使用不同的前綴,原因是 location 支持嚴格匹配、正則、前綴匹配等多種匹配方式,需要考慮匹配的優先級,相比與熟知匹配優先級,各個業務使用不同前綴更加易讀

image-20250613140346755

4、REWRITE

location 塊中的請求地址重寫階段,當 rewrite 指令用于 location 中時即運行

語法為:rewrite regex replacement [flag]

作用為將 regex 對應指定的 URL 替換成 replacement

其中 flag 字段有以下可選項:

  • last:用 replacement 這個 URL 進行新的 location 匹配
  • break:break 指令停止當前腳本指令的執行,等價于獨立的 break 指令
  • redirect:返回 302 臨時重定向
  • permanent:返回 301 永久重定向(永久重定向會被瀏覽器緩存)

新建一個這樣的目錄結構

[root@VM-16-11-centos nginx]# tree html/test/
html/test/
|-- first
|   `-- 1.txt
|-- second
|   `-- 2.txt
|-- third`-- 3.txt

配置文件:

server {listen 9093;rewrite_log on;root html/test;location /first {rewrite /first(.*) /second$1 last;return 200 'first!\n';}location /second {rewrite /second(.*) /third$1;return 200 'second!\n';}location /third {return 200 'third!\n';}}
[root@VM-16-11-centos ~]# curl 123.207.214.107:9093/first/1.txt
second!
[root@VM-16-11-centos ~]# curl 123.207.214.107:9093/first/2.txt
second![root@VM-16-11-centos ~]# curl 123.207.214.107:9093/second/3.txt
second!
[root@VM-16-11-centos ~]# curl 123.207.214.107:9093/second/2.txt
second!

出現上述響應的原因是 flag 標志的設置,訪問 /first/ 時被重寫為了 /second 并按照 last 這個 flag 的規則進行了重新匹配,而 /second 雖然進行了重寫,但未配置標志位,所以直接返回了 second 請求下的 200 響應

server {listen 9093;rewrite_log on;root html/test;location /first {rewrite /first(.*) /second$1 last;return 200 'first!\n';}location /second {rewrite /second(.*) /third$1 break;return 200 'second!\n';}location /third {return 200 'third!\n';}}
[root@VM-16-11-centos ~]# curl 123.207.214.107:9093/first/3.txt
3.txt
[root@VM-16-11-centos ~]# curl 123.207.214.107:9093/third/3.txt
third![root@VM-16-11-centos ~]# curl 123.207.214.107:9093/first/3
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.28.0</center>
</body>
</html>
[root@VM-16-11-centos ~]# curl 123.207.214.107:9093/third/3
third!

當 /second 對應的 flag 被設置為 break 后,url 重寫后不再進行 location 匹配,而是真正的去找對應的 /third/3

5、POST_REWRITE

請求地址重寫提交階段,防止遞歸修改 uri 造成死循環,(一個請求執行10次就會被 nginx 認定為死循環)該階段只由 ngx_http_core_module 模塊實現,無外部模塊

配置文件

    server {listen 9094;# 開啟日志,便于調試access_log logs/access_post_rewrite.log;error_log logs/post_rewrite_error.log debug;  # 啟用調試日志# 重寫規則location /loop {rewrite ^/loop(.*)$ /loop_rewritten\$1 last;return 200 "No loop detected\n";}# 默認返回location / {return 200 "Request processed successfully\n";}}

測試

[root@localhost nginx]# curl 123.207.214.107:9094/loop/1
<html>
<head><title>500 Internal Server Error</title></head>
<body>
<center><h1>500 Internal Server Error</h1></center>
<hr><center>nginx/1.28.0</center>
</body>
</html>

查看日志:

2025/06/13 15:55:34 [notice] 32345#0: *4474 rewritten data: "/loop_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\/1", args: "", client: 218.58.62.117, server: , request: "GET /loop/1 HTTP/1.1", host: "123.207.214.107:9094"
2025/06/13 15:55:34 [notice] 32345#0: *4474 "^/loop(.*)$" matches "/loop_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\/1", client: 218.58.62.117, server: , request: "GET /loop/1 HTTP/1.1", host: "123.207.214.107:9094"
2025/06/13 15:55:34 [notice] 32345#0: *4474 rewritten data: "/loop_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\/1", args: "", client: 218.58.62.117, server: , request: "GET /loop/1 HTTP/1.1", host: "123.207.214.107:9094"
2025/06/13 15:55:34 [notice] 32345#0: *4474 "^/loop(.*)$" matches "/loop_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\/1", client: 218.58.62.117, server: , request: "GET /loop/1 HTTP/1.1", host: "123.207.214.107:9094"
2025/06/13 15:55:34 [notice] 32345#0: *4474 rewritten data: "/loop_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\/1", args: "", client: 218.58.62.117, server: , request: "GET /loop/1 HTTP/1.1", host: "123.207.214.107:9094"
2025/06/13 15:55:34 [notice] 32345#0: *4474 "^/loop(.*)$" matches "/loop_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\/1", client: 218.58.62.117, server: , request: "GET /loop/1 HTTP/1.1", host: "123.207.214.107:9094"
2025/06/13 15:55:34 [notice] 32345#0: *4474 rewritten data: "/loop_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\/1", args: "", client: 218.58.62.117, server: , request: "GET /loop/1 HTTP/1.1", host: "123.207.214.107:9094"
2025/06/13 15:55:34 [error] 32345#0: *4474 rewrite or internal redirection cycle while processing "/loop_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\/1", client: 218.58.62.117, server: , request: "GET /loop/1 HTTP/1.1", host: "123.207.214.107:9094"

最后會出現: rewrite or internal redirection cycle while processing 的錯誤,即一直在循環

6、PREACCESS

訪問權限檢查準備階段,http 模塊介入處理階段,模塊 ngx_limit_conn 和 ngx_limit_req 就運行在此階段

ngx_limit_conn 顧名思義是限制連接個數的,而 ngx_limit_req 是限制請求數的,conn 即 tcp 連接,在一個 keepalive 周期內,所有的req 可以共用一個 conn

ngx_limit_conn

# 定義一個空間 名為 addr,存放二進制 ip 地址,大小為 10m
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {listen 9097;root html/;location / {limit_conn_status 500;		# 如果有多的連接返回 500 錯誤limit_conn_log_level  warn;limit_rate 50;				# 每秒返回 50Blimit_conn addr 1;			# 同時只能有 1 個連接}
}

開兩個終端測試

[root@VM-16-11-centos zwj]# curl localhost:9097/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@VM-16-11-centos zwj]# curl localhost:9097/
<html>
<head><title>500 Internal Server Error</title></head>
<body>
<center><h1>500 Internal Server Error</h1></center>
<hr><center>nginx/1.28.0</center>
</body>
</html>

也可以查看 access.log

127.0.0.1 - - [15/Jun/2025:13:59:40 +0800] "GET / HTTP/1.1" 500 177 "-" "curl/7.29.0"
127.0.0.1 - - [15/Jun/2025:13:59:49 +0800] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0"

ngx_limit_req

# 定義一個空間 名為 addr_req,存放二進制 ip 地址,大小為 10m,每分鐘最多處理 3 個請求
limit_req_zone $binary_remote_addr zone=addr_req:10m rate=3r/m;# limit_req 這里注意 burst 和 nodelay 選項
# burst 桶大小 緩存請求
# nodelay 超出桶大小后是否直接返回,nodelay 就是不延時,直接返回定義的錯誤信息
limit_req zone=addr_req burst=3 nodelay;
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_req_zone $binary_remote_addr zone=addr_req:10m rate=3r/m;server {listen 9097;root html/;location / {limit_conn_status 500;limit_conn_log_level  warn;limit_rate 50;limit_conn addr 1;#limit_req zone=one burst=3 nodelay;limit_req zone=addr_req;limit_req_status 503;}
}

也可以查看 error.log

2025/06/15 14:13:33 [error] 26915#0: *5530 limiting requests, excess: 0.882 by zone "addr_req", client: 127.0.0.1, server: , request: "GET / HTTP/1.1", host: "localhost:9097"
"logs/error.log" 175L, 21036C

7、ACCESS

訪問權限檢查階段,標準模塊 ngx_access,第三方模塊 nginx_auth_request 以及第三方模塊 ngx_lua 的 access_by_lua 指令運行在此階段,配置指令多是執行訪問控制性質的任務,比如檢查用戶的訪問權限,檢查用戶的來源 IP 地址是否合法

最常用的其實是 allow deny 指令,比如在系統開發完成給遠程客戶使用階段,可以指定允許訪問的 IP 塊

location / { deny 192.168.1.1; allow 192.168.1.0/24; allow 10.1.1.0/16; allow 2001:0db8::/32; deny all; 
}

這些指令是順序匹配,滿足其中一條后就不會繼續了

除此之外常用的還有 auth_basic 和 auth_request ,但這些模塊需要生成密碼文件來配置使用,有點麻煩這里就不再驗證了~

8、POST_ACCESS

在請求通過訪問控制之后,Nginx 執行這個階段的處理。這可以用于執行一些在訪問控制之后需要進行的操作。

9、TRY_FILES

如果 http 請求訪問靜態文件資源,try_files 配置項可以使這個請求順序地訪問多個靜態文件資源,直到某個靜態文件資源符合選取條件,重要部分為:try files 處理 和 mirrors

try files 允許我們在請求訪問靜態文件時,順序地嘗試訪問多個文件,直到找到一個符合條件的文件。如果沒有符合條件的文件,Nginx 會執行指定的備用操作。

目錄結構:

html/
|-- 403.html
|-- 50x.html
|-- index.html
|-- file
|   |-- assets
|   |   |-- 1.css
|   |   |-- 2.css
|   |   `-- default.css
|   `-- images
|       |-- 1.txt
|       |-- 2.txt
|       `-- default.txt

配置

    server {listen 9096;root html/file;  # 網站根目錄# 處理靜態文件location / {try_files $uri $uri/ /index.html;  # 依次嘗試 $uri、$uri/、index.html}# 針對特定路徑處理,比如 /images 目錄下的靜態文件location /images/ {try_files $uri $uri/ /images/default.txt;  # 嘗試訪問圖片目錄下的文件,如果文件不存在,使用默認}# 其他配置location /assets/ {try_files $uri /assets/default.css;  # 訪問 assets 目錄下的 CSS 文件,若不存在,使用默認樣式}}
[root@VM-16-11-centos nginx]# curl localhost:9096/
index
[root@VM-16-11-centos nginx]# curl localhost:9096/3.html
index[root@VM-16-11-centos nginx]# curl localhost:9096/images/111.txt
default
[root@VM-16-11-centos nginx]# curl localhost:9096/images/1.txt
1111.txt1111.txt1111.txt1111.txt1111.txt1111.txt1111.txt1111.txt1111.txt1111.txt1111.txt

mirror 處理請求時,生成子請求訪問其他服務,對子請求的返回值不做處理

10、CONTENT

內容產生階段,大部分HTTP模塊會介入該階段,是所有請求處理階段中最重要的階段,因為這個階段的指令通常是用來生成HTTP響應內容的

這里比較重要的部分包括:root/alias 的使用,index 和 autoindex 的使用

root 和 alias 的區別主要在于匹配到 location 后,最終的那個文件到底是加上 location 對應的前綴還是不加

[root@VM-16-11-centos nginx]# tree html/
html/
|-- 403.html
|-- 50x.html
|-- index.html
|-- root
|   `-- index.html

配置文件

server {listen       9095;location /root {root   html;}location /alias {alias   html;}}
[root@VM-16-11-centos nginx]# curl localhost:9095/alias/index.html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html>[root@VM-16-11-centos nginx]# curl localhost:9095/root/index.html
root/html[root@VM-16-11-centos nginx]# curl localhost:9095/alias/root/index.html
root/html

root 會將請求 url 完整的追加在其值的后面,而 alias 則會從請求 url 中先去除 location 匹配的部分再追加

index 指定 / 結尾的目錄訪問時,返回 index 文件內容

配置

server {listen       9095;charset utf-8;  # 編碼格式,不配置的話中文可能亂碼#access_log  logs/host.access.log  main;location / {root   html;index index.html index.htm;}error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}
}

image-20250613162550363

autoindex

    server {listen       9095;charset utf-8;	# 編碼格式,不配置的話中文可能亂碼#access_log  logs/host.access.log  main;location / {root   myHtml;autoindex on;                # 啟用目錄列表顯示autoindex_exact_size on;     # 可選:禁用文件大小顯示(以字節為單位)autoindex_localtime on;      # 可選:顯示本地時間}error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}}

image-20250613161823337

注意:index 模塊在 autoindex 之前,所以使用 autoindex 請務必關閉 index 或指定一個不存在的文件

11、LOG

日志模塊處理階段,記錄日志,正常會在 logs/access.log 中記錄 http 請求的日志信息

默認格式:

log_format combined '$remote_addr - $remote_user [$time_local] ' 
'"$request" $status $body_bytes_sent ' '"$http_referer" 
"$http_user_agent"';

可以根據需要自行修改,同時也會有日志壓縮和日志緩存的可配置項

日志格式

access_log path [format=name [buffer=size] [gzip[=level]] [flush=time] [if=condition]];access_log off;

  • path:日志文件的路徑,可以包含變量。
  • format:指定日志格式的名稱。
  • buffer:設置日志寫入的緩沖區大小。
  • gzip:啟用日志文件的壓縮,并可選地設置壓縮級別。
  • flush:設置日志刷新的頻率。
  • if:通過條件判斷來控制是否記錄日志。

日志緩存 日志緩存功能可以減少磁盤 I/O 操作,通過批量寫入日志來提高性能。

寫入磁盤的條件

  • 待寫入磁盤的日志大小超出緩存大小。
  • 達到 flush 指定的時間。
  • worker 進程執行 reopen 命令,或者正在關閉。

我只能說學到這里我大概知道 nginx 的每個階段可以做什么,具體的指令如果不是經常配置應該還是會忘記~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/85003.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/85003.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/85003.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

40-Oracle 23 ai Bigfile~Smallfile-Basicfile~Securefile矩陣對比

小伙伴們是不是在文件選擇上還默認給建文件4G/個么&#xff0c;在oracle每個版本上系統默認屬性是什么&#xff0c;選擇困難癥了沒&#xff0c;一起一次性文件存儲和默認屬性看透。 基于Oracle歷代在存儲架構的技術演進分析&#xff0c;結合版本升級和23ai新特性&#xff0c;一…

【一】零基礎--分層強化學習概覽

分層強化學習&#xff08;Hierarchical Reinforcement Learning, HRL&#xff09;最早一般視為1993 年封建強化學習的提出. 一、HL的基礎理論 1.1 MDP MDP&#xff08;馬爾可夫決策過程&#xff09;&#xff1a;MDP是一種用于建模序列決策問題的框架&#xff0c;包含狀態&am…

Java延時

在 Java 中實現延時操作主要有以下幾種方式&#xff0c;根據使用場景選擇合適的方法&#xff1a; 1. Thread.sleep()&#xff08;最常用&#xff09; java 復制 下載 try {// 延時 1000 毫秒&#xff08;1秒&#xff09;Thread.sleep(1000); } catch (InterruptedExcepti…

電阻篇---下拉電阻的取值

下拉電阻的取值需要綜合考慮電路驅動能力、功耗、信號完整性、噪聲容限等多方面因素。以下是詳細的取值分析及方法&#xff1a; 一、下拉電阻的核心影響因素 1. 驅動能力與電流限制 單片機 IO 口驅動能力&#xff1a;如 STM32 的 IO 口在輸入模式下的漏電流通常很小&#xf…

NY271NY274美光科技固態NY278NY284

美光科技NY系列固態硬盤深度剖析&#xff1a;技術、市場與未來 技術前沿&#xff1a;232層NAND架構與性能突破 在存儲技術的賽道上&#xff0c;美光科技&#xff08;Micron&#xff09;始終是行業領跑者。其NY系列固態硬盤&#xff08;SSD&#xff09;憑借232層NAND閃存架構的…

微信開發者工具 插件未授權使用,user uni can not visit app

參考&#xff1a;https://www.jingpinma.cn/archives/159.html 問題描述 我下載了一個別人的小程序&#xff0c;想運行看看效果&#xff0c;結果報錯信息如下 原因 其實就是插件沒有安裝&#xff0c;需要到小程序平臺安裝插件。處理辦法如下 在 app.json 里&#xff0c;聲…

UE5 讀取配置文件

使用免費的Varest插件&#xff0c;可以讀取本地的json數據 獲取配置文件路徑&#xff1a;當前配置文件在工程根目錄&#xff0c;打包后在 Windows/項目名稱 下 讀取json 打包后需要手動復制配置文件到Windows/項目名稱 下

【kdump專欄】KEXEC機制中SME(安全內存加密)

【kdump專欄】KEXEC機制中SME&#xff08;安全內存加密&#xff09; 原始代碼&#xff1a; /* Ensure that these pages are decrypted if SME is enabled. */ 533 if (pages) 534 arch_kexec_post_alloc_pages(page_address(pages), 1 << order, 0);&#x1f4cc…

C# vs2022 找不到指定的 SDK“Microsof.NET.Sdk

找不到指定的 SDK"Microsof.NET.Sdk 第一查 看 系統盤目錄 C:\Program Files\dotnet第二 命令行輸入 dotnet --version第三 檢查環境變量總結 只要執行dotnet --version 正常返回版本號此問題即解決 第一查 看 系統盤目錄 C:\Program Files\dotnet 有2種方式 去檢查 是否…

Pytest斷言全解析:掌握測試驗證的核心藝術

Pytest斷言全解析&#xff1a;掌握測試驗證的核心藝術 一、斷言的本質與重要性 什么是斷言&#xff1f; 斷言是自動化測試中的驗證檢查點&#xff0c;用于確認代碼行為是否符合預期。在Pytest中&#xff0c;斷言直接使用Python原生assert語句&#xff0c;當條件不滿足時拋出…

【編譯原理】題目合集(一)

未經許可,禁止轉載。 文章目錄 選擇填空綜合選擇 將編譯程序分成若干個“遍”是為了 (D.利用有限的機器內存,但降低了執行效率) A.提高程序的執行效率 B.使程序的結構更加清晰 C.利用有限的機器內存并提高執行效率 D.利用有限的機器內存,但降低了執行效率 詞法分析…

uni-app項目實戰筆記13--全屏頁面的absolute定位布局和fit-content自適應內容寬度

本篇主要實現全屏頁面的布局&#xff0c;其中還涉及內容自適應寬度。 創建一個preview.vue頁面用于圖片預覽&#xff0c;寫入以下代碼&#xff1a; <template><view class"preview"><swiper circular><swiper-item v-for"item in 5&quo…

OVS Faucet Tutorial筆記(下)

官方文檔&#xff1a; OVS Faucet Tutorial 5、Routing Faucet Router 通過控制器模擬三層網關&#xff0c;提供 ARP 應答、路由轉發功能。 5.1 控制器配置 5.1.1 編輯控制器yaml文件&#xff0c;增加router配置 rootserver1:~/faucet/inst# vi faucet.yaml dps:switch-1:d…

PCB設計教程【大師篇】stm32開發板PCB布線(信號部分)

前言 本教程基于B站Expert電子實驗室的PCB設計教學的整理&#xff0c;為個人學習記錄&#xff0c;旨在幫助PCB設計新手入門。所有內容僅作學習交流使用&#xff0c;無任何商業目的。若涉及侵權&#xff0c;請隨時聯系&#xff0c;將會立即處理 1. 布線優先級與原則 - 遵循“重…

Phthon3 學習記錄-0613

List&#xff08;列表&#xff09;、Tuple&#xff08;元組&#xff09;、Set&#xff08;集合&#xff09;和 Dictionary&#xff08;字典&#xff09; 在接口自動化測試中&#xff0c;List&#xff08;列表&#xff09;、Tuple&#xff08;元組&#xff09;、Set&#xff08…

UVa12298 3KP-BASH Project

UVa12298 3KP-BASH Project 題目鏈接題意輸入格式輸出格式 分析AC 代碼 題目鏈接 UVa12298 3KP-BASH Project 題意 摘自 《算法競賽入門經典&#xff1a;訓練指南》劉汝佳&#xff0c;陳鋒著。有刪改。 你的任務是為一個假想的 3KP 操作系統編寫一個簡單的 Bash 模擬器。由于操…

云打包生成的ipa上傳構建版本經驗分享

在上架ios應用&#xff0c;在蘋果開發者中心操作的時候&#xff0c;需要提供一個構建版本&#xff0c;如下圖所示&#xff1a; 點擊藍色加號&#xff0c;添加構建版本&#xff0c;但是點擊藍色加號后&#xff0c;并沒有構建版本可以選。 原因是需要下載下面它推薦的工具來上傳…

ESP32的spi通訊(Arduino)

目錄 一.基本配置 1.esp32-wroom-32引腳圖 2.接線方式 3.Arduino芯片選擇和庫文件 3.1Arduino配置&#xff08;2.0.11&#xff09; 3.2 下載ESP32SPISlave庫&#xff08;0.6.8&#xff09;文件 二、代碼編寫 1.主機代碼 2.從機代碼 3.注意事項 三、運行效果 一.基本…

Spring-rabbit重試消費源碼分析

在集成RabbitMQ與Spring Boot 3.1.x時&#xff0c;RetryOperationsInterceptor 是實現消息重試機制的關鍵組件。這里將深入分析 RetryOperationsInterceptor 的工作原理&#xff0c;尤其是在消費者消費失敗時的行為&#xff0c;并結合底層源碼進行詳解。 一、配置解析 首先&a…

如何使用JacksonTypeHandler處理mysql json字符串轉List對象的問題

在使用mysql5.7或更高版本時&#xff0c;json類型字段應用場景越來越多&#xff0c;對于普通的對象或者List<Integer>、List<String>這些基礎類型&#xff0c;jacksonTypeHandler都能很好的處理&#xff0c;如下&#xff1a; 1、定義一個person對象 import com.f…