Nginx 配置文件解析
參考文章:淺析 Laravel 官方文檔推薦的 Nginx 配置
server { # 代表一個獨立的 server
listen 80; # 監聽 80 端口
server_name example.com; # 域名配置
root /srv/example.com/public; # 站點根目錄,laravel 的要配置到 public 下。
# 添加幾條有關安全的響應頭;與 Google+ 的配置類似,詳情參見文末。
add_header X-Frame-Options "SAMEORIGIN"; # SAMEORIGIN:不允許被本域以外的頁面簽入,DENY:不允許被任何頁面嵌入
add_header X-XSS-Protection "1; mode=block"; # 啓用 xss 保護,檢查到攻擊時,停止渲染頁面
add_header X-Content-Type-Options "nosniff"; # 禁用瀏覽器的類型猜想
index index.php index.html index.htm; # 站點默認頁面,可以指定多個,按照順序匹配。
charset utf-8; # 指定字符集爲 utf-8
#laravel 默認重寫規則,刪除將導致 laravel 路由失效且 nginx 響應爲 404
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# 關閉 [/favicon.ico] 和 [/robots.txt] 的訪問日誌。
# 並且即使它們不存在,也不寫入錯誤日誌。
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
# 將 404 錯誤交給 index.php 處理,使用 laravel 渲染錯誤頁面,否則也可以定義一個頁面。
error_page 404 /index.php;
# URI 符合正則表達式 [\.php$]的請求將進入此段配置
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; # 配置 FastCGI 服務地址,可以爲 IP:端口,也可以爲 Unix socket。
fastcgi_index index.php; # 配置 FastCGI 的主頁爲 index.php。
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; #動態添加了一行 fastcgi 的配置,內容爲告知管理進程,cgi 腳本名稱。和下面的配置文件不衝突
include fastcgi_params; #引入 fastcgi 配置文件
}
# 除符合正則表達式 [/\.(?!well-known).*] 之外的 URI,全部拒絕訪問
# 也就是說,拒絕公開以 [.] 開頭的目錄,[.well-known] 除外
location ~ /\.(?!well-known).* {
deny all;
}
}
知識點:
1. try_files
try_files
指令可讓 Nginx 按照特定的順序查找文件。按照以下配置爲例:
try_files $uri $uri/ /index.php?$query_string;
假設你正在訪問 /api/status?query=example
:
- Nginx 會首先嚐試
$uri
是否存在(這是個 Nginx 內置變量,表示請求 URI),也就是/網站根目錄/api/status
。 - 如果
$uri
不存在,則嘗試$uri/
,也就是/網站根目錄/api/status/
。 - 如果
$uri/
也不存在,則最終嘗試/index.php?$query_string
($query_string
也是 Nginx 的內置變量,表示 URI 內的查詢字符串),也就是/網站根目錄/index.php?query=example
。 - 按照 Laravel 的目錄結構,
/網站根目錄/index.php
是必定存在的,但如果該文件確實不存在,Nginx 將會返回 404。
需要注意的是,嚴格地說,/api/status
與 /api/status/
這兩個 URI 並不指向同一個資源。同理,https://www.google.com
與 https://www.google.com/
也不等效。有興趣可 Google trailing slash in uri
之類的關鍵詞獲取更多細節。
2. fastcgi_pass 中配置的 nginx 和 php-fpm 之間的通信方式
參考文章:
-
unix socket 通信
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
-
tcp socket 通信
fastcgi_pass 127.0.0.1:9000;
區別:
由於 Unix socket 不需要經過網絡協議棧,不需要打包拆包、計算校驗和、維護序號和應答等,只是將應用層數據從一個進程拷貝到另一個進程。所以其效率比 tcp socket 的方式要高,可減少不必要的 tcp 開銷。不過,unix socket 高併發時不穩定,連接數爆發時,會產生大量的長時緩存,在沒有面向連接協議的支撐下,大數據包可能會直接出錯不返回異常。而 tcp 這樣的面向連接的協議,可以更好的保證通信的正確性和完整性。
tcp socket 的優點是可以跨服務器,當 nginx 和 php-fpm 不在同一臺機器上時,只能使用這種方式。還是推薦用 TCP Scoket 這種方式。