前言
這是我的 NGINX 學習筆記,看什麼學什麼記什麼!
安裝
sudo apt-get install nginx |
建立新的設定檔
vim /etc/nginx/sites-available/configName |
server { |
proxy_pass_header
: 若回應 request 時, header 有設定了, 那告訴 NGINX 不要更改設定的 header, 若要加 header 需使用 via, 例如 範例圖片server_name
: request 的 header 中的 server 需符合access_log
: log 的位置location
: 符合 server 後, 改搜尋相對應的 locationproxy_redirect
: 重新導向proxy_set_header
: 設定 header 值proxy_pass
: 將 request 導向指定的位置proxy_set_header
: set hostset $upstream_url
: set $upstream_urladd_header
: add headerbreak
: 終止目前的 rewrite 規則。 如果有規則是被指定在目前的 location 內的,繼續將此 location 的 request 處理完畢。
啟用設定檔
複製到 enabled 資料夾
ln -s /etc/nginx/sites-available/yourConfig /etc/nginx/sites-enabled |
啟用
systemctl restart nginx.service |
location
語法
Syntax: location [ = | ~ | ~* | ^~ ] uri { ... } |
規則搜尋分為以下兩種方式
- 正則搜尋 (regular expression)
~*
: 不區分大小寫~
: 區分大小寫
- 前綴字串 (prefix string)
- 正則搜尋 (regular expression)
規則搜尋順序:
使用前綴字串搜尋 → 搜尋到符合最長的 url, 並且記下結果 → 依照設定檔中的順序, 使用正則規則搜尋 → 如果正則規則有搜尋到符合的,會立即停止搜尋,因此正則順序至關重要 → 如果正則沒有搜尋到符合的,會採用使用前綴字串搜尋到的在一些不區分大小寫的系統中,像是 macOS 或是 Cygwin, 前綴字串規則會無視大小寫
正則規則可以捕捉一些變數,在其他的規則中使用
如果最長的前綴字串規則有
^~
, 那就不會再使用正則規則搜尋前綴規則有
=
, 代表字串須完全符合,如果有找到,搜尋終止。 例如,如果 “/“ 請求很頻繁,那麼可以定義 “location = /“, 這樣可以加速請求處理在版本 0.7.1 到 0.8.41 中,如果請求符合前綴規則,就算沒有加上
=
, 或者^~
, 搜尋也會立即停止
範例
location = / { |
- 請求
/
將會符合 A - 請求
/index.html
將會符合 B - 請求
/documents/document.html
將會符合 C - 請求
/images/1.gif
將會符合 D - 請求
/documents/1.jpg
將會符合 E - 請求
@name
: 只用於內部重新導向,不用於正常使用, 例如:location /img/ {
not_found 404 @not_found;
}
location @not_found {
# 规则
}
alias 與 root
alias
參考文件
定義特定 location 的替換。 舉例來說, 看看下面的設定
location /i/ { |
如果請求是 /i/top.git 的話, 檔案 /data/w3/images/top.git 將會被送出
路徑可以包含變數, 除了 $document_root 以及 $realpath_root 之外
如果 alias 被使用在正則定義的 location 之內, 那 alias 必須要參考正則捕捉到的條件, 範例如下:
location ~ ^/users/(.+\.(?:gif|jpe?g|png))$ { |
當 location 的值跟 alias 的最後一個資料夾的值相同, 像下面這樣:
location /images/ { |
那會建議使用 root
location /images/ { |
root
參考文件
設定 root 的資料夾位置為請求路徑, 例如以下範例:
location /i/ { |
/data/w3/i/top.git 檔案將會被送出, 以回應 /i/top.git 請求
路徑可以包含變數, 除了 $document_root 以及 $realpath_root 之外
總結
- alias 會取代 location
成為新的請求資源路徑
- root + location 的值 =
請求資源路徑
部署 vue 專案
Build
npm run build
, 看 script 怎麼寫, 這邊只管部署
config
server { |
upstream
語法
Syntax: upstream name { ... } |
範例
upstream backend { |
詳解
定義多個 server, server 可以 listen 不同的 port 號, TCP 以及 UNIX-domain socket 可以混用
預設的話, 會採用權重輪詢分配請求到不同的 server, 以上面的範例來看, 每 7 個 request 中, 5 個會被分配到 backend1.example.com
(weight=5), 2 個分別到 127.0.0.1:8080
以及 unix:/tmp/backend3
如果在溝通途中有錯誤, 請求會被分派到下一個 server, 直到出現成功回應的 server 。 如果裡面都沒有可以成功回應的, 那客戶端會收到最後一個 server 的回應 (backup)
PHP-FPM
fast
- 請求網址為
http://lemp.test/test.php/foo/bar.php?v=1
- 各項資訊如下:
array (
'USER' => 'www-data',
'HOME' => '/var/www',
'FCGI_ROLE' => 'RESPONDER',
'QUERY_STRING' => 'v=1',
'REQUEST_METHOD' => 'GET',
'CONTENT_TYPE' => '',
'CONTENT_LENGTH' => '',
'SCRIPT_FILENAME' => '/var/www/test.php',
'SCRIPT_NAME' => '/test.php',
'PATH_INFO' => '/foo/bar.php',
'REQUEST_URI' => '/test.php/foo/bar.php?v=1',
'DOCUMENT_URI' => '/test.php/foo/bar.php',
'DOCUMENT_ROOT' => '/var/www',
'SERVER_PROTOCOL' => 'HTTP/1.1',
'GATEWAY_INTERFACE' => 'CGI/1.1',
'SERVER_SOFTWARE' => 'nginx/1.4.0',
'REMOTE_ADDR' => '192.168.56.1',
'REMOTE_PORT' => '44644',
'SERVER_ADDR' => '192.168.56.3',
'SERVER_PORT' => '80',
'SERVER_NAME' => '',
'HTTPS' => '',
'REDIRECT_STATUS' => '200',
'HTTP_HOST' => 'lemp.test',
'HTTP_USER_AGENT' => 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:20.0) Gecko/20100101 Firefox/20.0',
'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'HTTP_ACCEPT_LANGUAGE' => 'en-US,en;q=0.5',
'HTTP_ACCEPT_ENCODING' => 'gzip, deflate',
'HTTP_CONNECTION' => 'keep-alive',
'PHP_SELF' => '/test.php/foo/bar.php',
'REQUEST_TIME' => 1367829847,
)
Questions and Answers
以下的 Nginx configuration example 的意思是?
- Example:
proxy_http_version 1.1;
- Answer:
將 http version 設定為 1.1, 預設為 1.0
1.0 是不會開啟 keep-alive feature 在 proxy server 跟 backend 的
Nginx 中, 何時可能會用到 proxy_set_header?
當我想要使用預設的 variable 來設定 header 時, 例如取得 $remote_addr
以下的 Nginx 設定的意思是?
Example:
server {
listen 80;
underscores_in_headers on;
location / {
if ($http_custom_header = ray) {
proxy_pass http://127.0.0.1:3000;
}
}
}Answer:
使用 custom variable, 會自動 assign request header namecustom_header
title column collection 的 value 到 $http_custom_header 這個變數中, 所以如果我在 request header 使用custom_header
:ray
的話, 就會 pass 到 http://127.0.0.1:3000;
參考 Nginx document以下的設定中,
location ~ \.php$
中, 最終帶過去的 fastcgi_param 是什麼? $query_string, 原本的 $request_method 跟 $document_root, $fastcgi_script_name 會處於未設定# server context
root /var/www/html;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_index index.php;
location /scripts {
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
location ~ \.php$ {
fastcgi_param QUERY_STRING $query_string;
fastcgi_pass 127.0.0.1:9000;
}在以下的設定中, 如果使用 PHP-FPM 的話, 最終傳出的 fastcgi_param TEST 跟 DOCUMENT_ROOT 是? three, override
# server context
location ~ \.php$ {
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param SCRIPT_FILENAME $request_uri;
fastcgi_param DOCUMENT_ROOT initial;
fastcgi_param DOCUMENT_ROOT override;
fastcgi_param TEST one;
fastcgi_param TEST two;
fastcgi_param TEST three;
fastcgi_pass 127.0.0.1:9000;
}不同的 FastCGI 處理器的作用方式依樣嗎? 不同哦
因為不同的 FastCGI 處理器行為不同, 所以宣告 fastcgi_param 時, 建議宣告幾次? 1次
當我們使用 PHP-FPM, 要 pass fastcgi_params 時, 怎樣可以在不同的 location 中在保留共同變數的同時, 又可以客制新的變數? 使用 include 共同檔案, 如下:
root /var/www/html;
location /scripts {
include fastcgi_common;
fastcgi_index index.php;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
location ~ \.php$ {
include fastcgi_common;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
}CGI 全寫? Common Gateway Interface
Fast CGI 全寫? Fast Common Gateway Interface
CGI 用途? 一份協議, 規定要傳哪些數據, 以什麼樣的格式給後端
Fast CGI 用途? 依據 CGI 協議, 將請求以及數據傳給後端這個動作, 每一次都會產生一個程序, Fast CGI 會啟動一個主程序, 並將工作分配給子進程處理, 避免重複的勞動, 提高效率
PHP-FPM 全寫? PHP-Fast CGI Process Manager
PHP-FPM 用途? PHP 針對 FastCGI 的實現
如何使用 systemctl 啟動 Nginx
sudo systemctl start nginx
如何使用 systemctl, 預設開機啟動 NGINX?
sudo systemctl enable nginx
如何使用 systemctl, 停止 nginx?
sudo systemctl stop nginx
如何使用 systemctl, 重啟 nginx?
sudo systemctl restart nginx
如何使用 systemctl, 重新載入 nginx 配置文件?
sudo systemctl reload nginx
如何測試 nginx 配置?
sudo nginx -t
如何使用 systemctl, 顯示 nginx 狀態?
sudo systemctl status nginx
如何檢查 nginx 版本?
sudo nginx -v
在 NGINX 中如果我想要從本地帶客製的 header 到 server, 該 header 的 key 有 underscore, 該怎麼解決?
在 NGINX server block 中加入以下設定
underscores_in_headers on;NGINX 中, location 的規則搜尋, 又區分為哪兩種?
1. 正則搜尋
2. 前贅字串NGINX 中, location 的正則搜尋中,
~*
代表的意思是? 不區分大小寫NGINX 中, location 的正則搜尋中,
~
代表的意思是? 區分大小寫NGINX 中, location 的規則搜尋的順序?
1. 使用前綴字串搜尋
2. 搜尋到符合最長的 uri, 記錄下來
3. 依照設定檔中的順序, 使用正則搜尋
4. 若正則有找到, 停止搜尋, 以正則的為主
5. 若正則沒找到, 以前最字串為主NGINX 中, location 的規則搜尋的順序, 會先使用哪種規則搜尋? 前贅字串
NGINX 中, location 的規則搜尋的順序, 前綴字串搜尋結束後, 會使用什麼規則搜尋? 正則
NGINX 中, location 的規則搜尋的順序, 若再找到符合的前綴字串後, 還是使用正則搜尋一次嗎?? 會
NGINX 中, location 的規則搜尋的順序, 若正則規則找到符合的, 還會繼續搜尋嗎? 不會
NGINX 中, location 的規則搜尋的順序, 若前綴跟正則都有符合的, 以哪種為優先? 正則
NGINX 中, location 的規則搜尋中, macOS 會區分大小寫嗎? 不會
NGINX 中, location 的規則搜尋中, 如何捕捉變數? 使用正則
NGINX 中, location 的規則搜尋中,
^~
代表什麼意思? 當使用^~
的前綴有找到符合的, 不會再使用正則搜尋NGINX 中, location 的規則搜尋中,
^~
是用於前綴還是正則? 前綴NGINX 中, location 的規則搜尋中,
=
是用於前綴還是正則? 前綴NGINX 中, location 的規則搜尋中,
=
代表什麼意思? 前綴須完全符合, 若有找到, 搜尋停止NGINX 中, location 的規則搜尋中, 如果
/
的搜尋非常頻繁, 可以使用什麼樣的規則來加快速度?= /
NGINX 中, location 的規則搜尋中, 下圖中, 請求
/
會符合哪一個? Alocation = / {
[ configuration A ]
}
location / {
[ configuration B ]
}
location /documents/ {
[ configuration C ]
}
location ^~ /images/ {
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
[ configuration E ]
}NGINX 中, location 的規則搜尋中, 下圖中, 請求
/index.html
會符合哪一個? Blocation = / {
[ configuration A ]
}
location / {
[ configuration B ]
}
location /documents/ {
[ configuration C ]
}
location ^~ /images/ {
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
[ configuration E ]
}NGINX 中, location 的規則搜尋中, 下圖中, 請求
documents/document.htm
會符合哪一個? Clocation = / {
[ configuration A ]
}
location / {
[ configuration B ]
}
location /documents/ {
[ configuration C ]
}
location ^~ /images/ {
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
[ configuration E ]
}NGINX 中, location 的規則搜尋中, 下圖中, 請求
images/1.gif
會符合哪一個? Dlocation = / {
[ configuration A ]
}
location / {
[ configuration B ]
}
location /documents/ {
[ configuration C ]
}
location ^~ /images/ {
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
[ configuration E ]
}NGINX 中, location 的規則搜尋中, 下圖中, 請求
@name
可否用於正常使用? 不可
location /img/ { |
NGINX 中, alias 與 root 的規則中, 下圖中, 如果請求
/i/top.gif
那哪一個檔案會被送出?/data/w3/images/top.gif
location /i/ {
alias /data/w3/images/;
}NGINX 中, alias 與 root 的規則中, 下圖中, 如果像下圖般有使用到變數, 該從哪裡取變數? location
location ~ xxx { |
- NGINX 中, alias 與 root 的規則中, 如下圖般, 當 location 以及 alias 的最後一個資料夾的值相同時, 建議如何?
location /images/ {
root /data/w3;
}
location /images/ { |
- NGINX 中, alias 與 root 的規則中, 如下圖般, 如果請求是
/i/top.gif
, 哪個檔案會被送出?/data/w3/i/top.gif
location /i/ { |
NGINX 全域變數中, $document_root 是什麼? 當前請求的文檔根目錄或別名
NGINX 全域變數中, 下面的 request url 中, $document_uri 是哪一段? /test1/test2
http://34.83.35.165/test1/test2?test1=123&test2=456
NGINX 全域變數中, 下面的 request url 中, $host 是哪一段? 34.83.35.165
http://34.83.35.165/test1/test2?test1=123&test2=456
NGINX 全域變數中, $hostname 是什麼? 主機名稱, 可在 Linux 中設定
NGINX 全域變數中, $is_args 是什麼? 如果請求中有參數,值為“?”,否則為空字符串。
NGINX 全域變數中, $limit_rate 是什麼? 用於設置響應的速度限制,詳見limit_rate。
NGINX 全域變數中, $msec 是什麼? 當前的Unix時間戳(1.3.9, 1.2.6)
NGINX 全域變數中, $pipe 是什麼? 如果請求來自管道通信,值為“p”,否則為“.”
NGINX 全域變數中, 下面的 request url 中, $query_string 是哪一段? test1=123&test2=456
http://34.83.35.165/test1/test2?test1=123&test2=456
NGINX 全域變數中, $realpath_root 是什麼? 當前請求的文檔根目錄或別名的真實路徑,會將所有符號連接轉換為真實路徑, 位置同 document_root
NGINX 全域變數中, $remote_addr 是什麼? 客戶端地址
NGINX 全域變數中, $remote_port 是什麼? 客戶端端口
NGINX 全域變數中, $request 是什麼? 代表客戶端的請求地址, 像這樣:
POST /test1/test2?test1=123&test2=456 HTTP/1.1
NGINX 全域變數中, $request_body 是什麼? 客戶端的請求主體, 此變量可在location中使用,將請求主體通過proxy_pass, fastcgi_pass, uwsgi_pass,和scgi_pass傳遞給下一級的代理服務器。
NGINX 全域變數中, $request_filename 是什麼? 當前連接請求的文件路徑,由root或alias指令與URI請求生成。
/usr/share/nginx/html/test1/test2
NGINX 全域變數中, $request_length 是什麼? 請求的長度(包括請求的地址, http請求頭和請求主體) (1.3.12, 1.2.7)
NGINX 全域變數中, $request_method 是什麼? HTTP請求方法,通常為“GET”或“POST”
NGINX 全域變數中, $request_time 是什麼? 處理客戶端請求使用的時間(1.3.9, 1.2.6); 從讀取客戶端的第一個字節開始計時。
NGINX 全域變數中, 下面的 request url 中, $request_uri 是哪一段?
/test1/test2?test1=123&test2=456
這個變量等於包含一些客戶端請求參數的原始URI,它無法修改,請查看$uri更改或重寫URI,不包含主機名,例如:”/cnphp/test.php?arg=freemouse”。http://34.83.35.165/test1/test2?test1=123&test2=456
NGINX 全域變數中, $scheme 是什麼? 請求使用的Web協議, “http” 或“https”
NGINX 全域變數中, $sent_http_name是什麼? 可以設置任意http響應頭字段; 變量名中的後半部分“name”可以替換成任意響應頭字段,如需要設置響應頭Content-length,那麼將“-”替換為下劃線,大寫字母替換為小寫,形如:$sent_http_content_length 4096即可。
NGINX 全域變數中, $server_addr 是什麼? 服務器端地址,非外部 IP, 機器在該網域的地址
NGINX 全域變數中, $server_port 是什麼? 服務器端口
NGINX 全域變數中, $server_protocol 是什麼? 服務器的HTTP版本, 通常為“HTTP/1.0” 或“HTTP/1.1”
NGINX 全域變數中, $status 是什麼? HTTP status code
NGINX 全域變數中, $time_iso8601 是什麼? 服務器時間的ISO 8610格式, 如
2019-11-27T14:11:04+00:00
NGINX 全域變數中, $time_local 是什麼? 服務器時間(LOG Format 格式)
27/Nov/2019:14:11:38 +0000
NGINX 全域變數中, $uri 是什麼? 請求中的當前URI(不帶請求參數,參數位於$args),可以不同於瀏覽器傳遞的$request_uri的值,它可以通過內部重定向,或者使用index指令進行修改,$uri不包含主機名,如”/foo/bar.html”。
NGINX 全域變數中, 下面的 request url 中, $uri 是哪一段?
/test1/test2
http://34.83.35.165/test1/test2?test1=123&test2=456
參考以下的 NGINX 設定, 並思考接下來一連串的問題
upstream backend {
server backend1.example.com weight=5;
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
server backup1.example.com backup;
}
server {
location / {
proxy_pass http://backend;
}
}以上的 nginx 設定中, 到
/
的請求會被送到哪裡?
upstream backend以上的 nginx 設定中, 每七個請求中, 會有幾個到 backend1.example.com? 為什麼?
5 個
因為 weight=5以上的 nginx 設定中, 每七個請求中, 會有幾個到 127.0.0.1:8080? 為什麼?
1 個
因為沒有特別分配權重, 預設平均分配以上的 nginx 設定中, 每七個請求中, 會有幾個到 unix:/tmp/backend3 為什麼?
1 個
因為沒有特別分配權重, 預設平均分配以上的 nginx 設定中, 如果送給 server 127.0.0.1:8080 出錯了, 會怎麼樣?
送往下一個, 即 unix:/tmp/backend3以上的 nginx 設定中, 如果 upstream 中的 server 都無法服務, 會怎麼樣?
送給 backup server, 即 backup1.example.com, 客戶會收到這一個 server 的回應
NGINX Cookbook
- NGINX 中, root 語法的意思是什麼?
將會在 root 所定義的位置中尋找請求中帶過來的 URL 部分
留言