Nginx-包教包會-入門

前言

Nginx 做爲 web 服務器 以低內存,高擴展,而且輕鬆單機支持 1-3w (聽說能夠單機 10w,但沒有看到具體的機器配置)的併發連接的特性廣受開發人員的青睞。javascript

推薦在 linux 系統上使用 Nginx ,這會充分利用 linux 的特性,性能比在 windows 上會更好。css

本文主要內容:html

  • Nginx 簡單配置
  • root 和 alias 的區別
  • location 的優先級及驗證
  • Nginx 內置變量介紹
  • if
  • rewrite 轉發
  • try_files
  • 配置 gzip
  • 協商緩存和強緩存的介紹和配置

後續章節,我會使用 ab 壓測來一步一步優化 Nginx 的配置,Nginx 知道原理,懂得經常使用配置便可。有的性能優化須要瞭解 linux 內核 、httptcp 相關的東西,若是你不想了解,能夠記錄一份本身的配置便可,沒必要糾結爲何。java

本文內容在 nginx 1.16.1 上測試,Centos 7 4核 8g 內存的虛擬機。linux

Nginx 安裝

Nginx 安裝步驟

根據 阿里 CentOS 鏡像 配置 yum 源,提升下載速度。webpack

阿里 epel 鏡像 配置咱們經常使用軟件的包,Nginx 也在其中。nginx

# 運行一下命令,更新 yum 源 yum clean all yum makecache 

刷新 yum 倉庫信息以後,運行如下命令就能夠找到 nginxweb

yum list | grep nginx

安裝 nginx正則表達式

sudo yum install nginx

配置 nginx 開機啓動json

sudo systemctl enable nginx 

啓動 nginx

sudo systemctl start nginx

檢查 nginx 是否啓動

sudo systemctl status nginx

image-20200327220547818

若是想查看 nginx包都安裝了哪些文件,可使用

rpm -qvl nginx

image-20200327221058643

Nginx 命令

# 強制當即關閉,不建議作 nginx -s stop # 正常關閉,會處理已經接到的請求,但不會接受新的請求 nginx -s quit # 從新加載配置文件 nginx -s reload # 從新打開日誌文件 nginx -s reopen # 檢查配置文件是否有誤 nginx -t # 檢查配置文件是否有誤,會將配置文件內容打印 nginx -T # 查看 nginx 版本 nginx -v # 查看 nginx 版本和編譯配置致殘 nginx -V 

系統開啓、關閉、重啓、查看 nginx 命令

sudo systemctl enable nginx sudo systemctl start nginx sudo systemctl restart nginx sudo systemctl stop nginx sudo systemctl status nginx 

Nginx 簡單配置

Nginx 介紹

部署的 Nginx 使用一個 master 進程管理多個 worker 進程。master 進程不處理請求,提供管理服務,包括啓動、中止、重載配置文件等服務,一般以 root 用戶啓動, worker 進程進行請求的處理,通常用非管理員帳戶啓用,worker 進程數量和 cpu 核心設置一直,下降進程切換帶來的 cpu 切換。

image-20200327222127446

http 上下文中的配置是咱們重點須要知道的,其他的瞭解會配置便可。

Server 配置

http { include /etc/nginx/mime.types; default_type application/octet-stream; server { listen 80 ; server_name _; root /usr/share/nginx/html; location / { } } } 

Server 既配置一個服務。

listen 80 用於配置監聽 80 端口的服務。

root 指定靜態資源存放的位置。

location 進行資源匹配。location / {} 匹配全部的資源。

listen 和 server_name 配置

匹配規則:

  • 先匹配 listen 再匹配 server_name
  • server_name 匹配請求頭中的 Host
  • 當都沒有匹配成功,由配置default_server 的處理
  • 以上都沒有匹配成功,由第一個配置處理
server { listen 9099 default_server; server_name "localhost"; location / { return 200 "server_name 爲 localhost"; } } server { listen 9099; server_name 127.0.0.1; location / { return 200 "server_name 爲 127.0.0.1"; } } server { listen 9099; server_name "localhost77"; location / { return 200 "server_name 爲 localhost77"; } } 

在 Postman中設置請求頭 Host 模擬訪問。

http://localhost:9099 Host:127.0.0.1 返回 server_name 爲 127.0.0.1

http://localhost:9099 Host:localhost 返回 server_name 爲 localhost

http://localhost:9099 Host:localhost77 返回 server_name 爲 localhost77

http://localhost:9099 Host:localhost779 返回 server_name 爲 localhost

再添加一個配置

server { listen localhost:9099 default_server; server_name "localhost"; location / { return 200 "server_name 爲 localhost:9099"; } } 

當 listen 訪問 localhost:9099 的時候,返回 server_name 爲 localhost:9099 ,由於只有這一個匹配上了。

若是想禁止沒有 Host 請求頭的訪問。

server { listen 80; server_name ""; # 表示 nginx 會關閉鏈接 return 444; } 

return 配置

return 用於定義返回的狀態碼,或者內容。

介紹 return 主要是爲了好描述 location 配置

- 說明
語法 return code [text];<br/>return code URL;<br/>return URL ;
默認 -
上下文 server、location、if

code 爲狀態碼。text 爲字符串。

location /a { default_type application/json; return 200 "訪問 9088/a"; } 
# 重定向 location = /b { return 301 http://www.baidu.com; } 

location 配置

location 用於匹配資源。

<font color=red>數字越小,優先級越高。</font>

規則符號 描述 優先級
location = /a{} 精準徹底匹配,匹配到以後 1
location ^~ /a{} 前綴匹配,匹配到以後 2
location ~ /a.*{} 正則匹配,區分大小寫,檢查到以後,還會檢查有沒有優先級跟高的 3
location ~* /a.* 正則匹配,不區分字母大小寫,檢查到以後,還會檢查有沒有優先級跟高的 4
location /a {} 也表示前綴匹配,可是優先級低於 正則匹配。 /a 和 ^~/a 會衝突,報錯 5
location / {} 任何沒有匹配成功的,都會匹配這裏處理 6
server { listen 9088 default_server; server_name _ ; location = /a { default_type application/json; return 200 "= /a,優先級第一"; } location ^~ /a { default_type application/json; return 200 "^~ /a 匹配 /a 開頭的路徑,優先級第二"; } location ~ /a\.* { default_type application/json; return 200 " /a\.* 匹配 /a...路徑,優先級第三"; } location ~* /a\.* { default_type application/json; return 200 "~* /a\.* 匹配 /a...路徑,優先級第四"; } # /a 會和 ^~ /a 衝突 location /a/ { default_type application/json; return 200 "/a/ 匹配 /a/...路徑,優先級第五"; } } 

訪問 http://localhost:9088/a ,依次註釋優先級較高的,能夠驗證這個規律。

還有一類特殊的 location 用於配置跳轉的,以 @ 開頭

location @pass { } 

add_header 添加響應頭

- 說明
語法 add_header name value [always];
默認 -
上下文 http、server、location、location 中的 if

若是響應代碼等於 200、20一、20四、20六、30一、30二、30三、30四、307或 308,則將指定的字段添加到響應報頭中。

加上 always 無論什麼狀態碼都加上。

location ~ /a\.* { default_type application/json; add_header test1 "asdfasdf" always; return 200 " /a\.* 匹配 /a...路徑,優先級第三"; } 

error_page

- 說明
語法 error_page code …[=[response code]] uri;
默認 -
上下文 http、server、location、location 中的 if

配置錯誤狀態碼跳轉頁面。

error_page 404 /404.html; error_page 500 502 503 504 /50x.html; 

以上不會改變響應狀態碼。

# 改變響應狀態嗎。 error_page 404 =200 /404.html; 
server { location / { error_page 404 = @ops-coffee; } location @ops-coffee { rewrite .* / permanent; } } 

root 和 alias 的區別

alias 理解爲:路徑替換,location 以 / 結尾,alias 必須以 / 結尾。嚴格匹配。alias 替換掉 location 路徑。

# /bieming/ 替換 /usr/local/var/www/alias2/ # 訪問 /bieming/1.jpg 去尋找 /usr/local/var/www/alias2/1.jpg location /bieming/ { alias /usr/local/var/www/alias2/; } 

root 理解爲:root 路徑加上 + location 路徑。會將兩個或更多個 / 壓縮成一個。

# 當 location 和 root 路徑的最後一部分匹配時,更好的方式是使用 root ## 如下配置均可以。 # 訪問 /data2/1.jpg 去尋找 /usr/local/var/www/data2/1.jpg location /data2/ { root /usr/local/var/www; } location /data2/ { root /usr/local/var/www/; } location /data2 { root /usr/local/var/www; } location /data2 { root /usr/local/var/www/; } location /data2/ { root /usr/local/var/www////; } 

內置變量

經過內置變量,咱們能夠經過判斷請求頭、query string 等值來轉發或者拒絕訪問。

$arg_name 獲取請求參數

獲取請求query string 中的 name 參數。

location /arg/ { default_type application/json; return 200 "$arg_q1"; } 

/arg/a?q1=334 返回的內容爲 334

$args 獲取請求 query_string 參數

location /arg/ { default_type application/json; return 200 "$arg_q1 _ $args"; } 

瀏覽器訪問 /arg/a?q1=3334&aa=2&bb=33 返回的內容爲 3334 _ q1=3334&aa=2&bb=33

$cookie_name 獲取cookie的值

獲取請求中的名稱爲 name 的 cookie。

$http_name 獲取請求頭

name 爲請求頭中的字段名稱,請求頭名稱所有小寫,並將破折號- 替換爲下劃線 _

$http_user_agent 獲取請求頭中的 User-Agent 字段。

$uri 獲取請求路徑中的 path

path 爲端口後面的路徑,不包括 query string。優化以後的路徑,特殊字符轉譯及 / 壓縮。

http://localhost:8888/arg/a?q1=q1canshu&bb=2323 中的 path 爲 /arg/a

$host 獲取請求的 ip

首先會獲取請求頭 Host ,若是沒有請求頭中沒有 Host 請求頭,那麼獲取的是 url 中的 ip

$request_uri 獲取 path 和 query string

訪問 http://localhost:8888/arg/a/?q1=q1canshu&bb=2323

$request_uri 爲/arg/a/?q1=q1canshu&bb=2323

$scheme 獲取請求協議

值爲 http 或 https

$request_method 獲取請求方法

得到的值字母全大寫。GET,POST,DELETE,PUT 等

其餘變量

- 描述
$content_length 獲取 Content-Length 請求頭字段。
$content_type 獲取 Content-Type 請求頭字段
$https 若是鏈接以 SSL 模式運行,則爲 on ,不然爲空字符串
$is_args 若是請求行有參數則爲 ? ,不然爲空字符串
$pid 獲取處理當前請求的 worker pid
$nginx_version 獲取 nginx 的版本
   

if

- 說明
語法 if (condition){}
默認 -
上下文 server、location

指定的 condition 求值以後,若是爲 true ,則執行在大括號內指定的該模塊的指令,並在 if 指令內爲該請求分配配置。 if 指令內的配置繼承自上一層的配置級別。

condition 能夠是如下任何一種:

  • 變量名,若是變量的值爲空字符串或 0 ,則爲 false

  • 使用 = 和 != 運算符比較變量和字符串

  • 使用 ~ (區分大小寫的匹配)和 ~* (不區分大小寫的匹配)運算符,變量將與正則表達式進行匹配。正則表達式能夠包含可供之後在 $1..$9 變量中重用的捕獲。

  • 反操做符 !~ 和 !~* 也可用。若是正則表達式包含 } 或 ; 字符,則整個表達式應使用單引號 或雙引號包圍起來。

  • 使用 -f 和 !-f 運算符檢查文件是否存在

  • 使用 -d 和 !-d 運算符檢查目錄是否存在

  • 使用 -e 和 !-e 運算符檢查文件、目錄或符號連接是否存在

  • 使用 -x 和 !-x 運算符檢查是否爲可執行文件

<font color=red>if 與小括號之間須要有空格</font>

location = /a { default_type application/json; if ($request_uri ~* "/(a).*") { return 200 "正則表達式捕獲的值:$1"; } return 200 "= /a,優先級第一"; } 

rewrite

- 說明
語法 rewrite regex replacement [flag];
默認 -
上下文 server、location、if

flag 可選參數:

  • last

中止匹配,發送一個新的請求去匹配 location

  • break

中止匹配,在當前 location 去搜索資源。

  • redirect

臨時重定向。返回狀態碼 302

  • permanent

永久重定向。返回狀態碼 301 。

指定的 regex 能匹配,uri 將根據 replacement 來處理。

驗證 break 和 last

如下三張圖片都存在,可是內容不同。

/Users/zhangpanqin/stduy_app/break2/test/1.jpg

/Users/zhangpanqin/stduy_app/last2/test/1.jpg

/Users/zhangpanqin/stduy_app/test/1.jpg

location /break2 { root /Users/zhangpanqin/stduy_app/break2; rewrite /break2/(.*) /test/$1 break; } location /last2 { root /Users/zhangpanqin/stduy_app/last2; rewrite /last2/(.*) /test/$1 last; } location /test/ { root /Users/zhangpanqin/stduy_app; } 

當訪問 /break2/1.jpg 實際匹配第一個 location,而後在當前上下文處理 。

/break2/1.jpg 被替換爲 /test/1.jpg 來處理了,而後和 root 指定的路徑相結合,返回 /Users/zhangpanqin/stduy_app/break2/test/1.jpg 數據。

當訪問 /last2/1.jpg ,uri 被替換爲 /test/1.jpg 去匹配新的 location 進行處理。

返回 /Users/zhangpanqin/stduy_app/test/1.jpg 的內容。

驗證 redirect 和 permanent

location /redirect2 { rewrite ^/redirect2 http://www.baidu.com redirect; } location /permanent2 { rewrite ^/permanent2 http://www.baidu.com permanent; } 

兩者匹配成功以後,都會改變瀏覽器地址欄地址。瀏覽器根據響應頭 Location 跳轉對應地址。

兩者的區別在於,永久重定向 (permanent),瀏覽器會保存記錄,當再訪問 http://localhost:9088/permanent2 而不會詢問 nginx 直接跳轉。

臨時重定向,瀏覽器每次都要詢問 nginx 須要跳轉到哪裏。能夠關閉 nginx 就知道驗證結果了。

image-20200328181255172

try_files

- 說明
語法 try_files file … uri;<br/>try_files file … =code;
默認 -
上下文 server、location

以指定順序檢查文件是否存在,並使用第一個找到的文件進行請求處理。若是找不到內容內部轉發到最後一個參數 uri 。文件位置爲 root + file

location /try/ { root /usr/local/var/www/data2/data2/; try_files $uri $uri/ @pass2; } location @pass2 { default_type application/json ; return 200 "沒到到頁面代理的數據" ; } 

訪問 /try/1.jpg 時,$uri 爲 /try/1.jpg 。

root + $uri 爲 /usr/local/var/www/data2/data2/try/1.jpg 找到返回,沒有找到繼續匹配返回。都沒有匹配內部轉發至 @pass2

如想驗證跳轉使用 /try/test 之類的,不要使用後綴名,由於使用後綴名的話,瀏覽器會返回 content-type,致使內容與解析不一致,圖片出不來。

配置 gzip

# 開啓 gzip gzip on; # 在響應頭中增長,Vary: Accept-Encoding gzip_vary on; # gzip壓縮級別1-9,數字越大壓縮效果越好,壓縮所用時間也就越長,佔用CPU越高 gzip_comp_level 6; # 申請內存時大小,若是源文件 9k,超過了 8K,那會申請 16*8K。 gzip_buffers 16 8k; gzip_min_length 2K; gzip_proxied any; gzip_disable "msie6"; gzip_http_version 1.1; # 文本(js、text、css、xml、json)壓縮比較好,圖片已經進行過壓縮,在壓縮,效果不是很明顯,還浪費 cpu gzip_types text/plain text/css text/xml text/javascript application/javascript application/json application/xml+rss application/rss+xml application/atom+xml image/svg+xml; 

gzip 壓縮對文本效果比較好,推薦只對文本之類的壓縮。

配置緩存

爲了減輕服務器壓力,節省帶寬,能夠配置緩存。

image-20200328185715962

memory cache:它是將資源文件緩存到內存中,緩存有效直接從內存加載。

disk cache: 它是將資源文件緩存到硬盤中,緩存有效直接從硬盤中加載。

先從 memory cache 找,找不到從 disk cache 找,再找不到,請求網絡資源。

緩存分爲 協商緩存 和 強緩存

協商緩存 每次都要去服務器詢問緩存是否過時,沒有過時使用本地的緩存。

強緩存 會有緩存過時時間,在有效期內不會去服務端校驗緩存,直接使用本地緩存。

如今的 webpack 能夠根據文件內容的 hash 生產相似 app.asdfa21342.js 這樣的文件。其實就是想使用強緩存,當網站更新,新的頁面會解析加載不同的資源,從而下降緩存校驗對服務器性能的損耗。

協商緩存

協商緩存有:ETag/if-None-Match 和 Last-Modified/if-Modify-Since 兩種。

http 協議規定,當這兩種響應頭都存在的時候,必須都要知足,才能使用緩存。

ETag/if-None-Match

- 說明
語法 etag on|off;
默認 etag on;
上下文 http、server、location

nginx 有個 etag 配置屬性,會給每一個靜態資源生成 Etag 響應頭,值爲文件內容 hash

當瀏覽器第一次訪問資源的時候,返回的響應頭中攜帶 Etag 。

後續的正常訪問(不強制刷新緩存)相同的資源,都會帶上請求頭 if-None-Match ,值爲 Etag 去 nginx 校驗是否同樣,同樣說明緩存沒有過時,返回狀態碼 304,直接訪問瀏覽器中的緩存,不然從瀏覽器返回資源,返回狀態碼 200。

Last-Modified/if-Modify-Since

- 說明
語法 if_modified_since off|exact|before;
默認 if_modified_since exact;
上下文 http、server、location

指定如何比較文件的修改時間與請求頭 If-Modified-Since 進行比較:

  • off

忽略 If-Modified-Since 請求頭字段(0.7.34)

  • exact

徹底匹配

  • before

資源的修改時間小於或等於 If-Modified-Since 請求頭字段中的時間

瀏覽器第一次訪問一個資源的時候,響應頭 Last-Modified 返回,標識文件的最後修改時間。

當瀏覽器再次正常訪問(不強制刷新資源)相同資源,請求頭會加上 If-Modified-Since,該值爲以前返回的 Last-Modifiednginx 收到 If-Modified-Since 後,根據配置 if_modified_since 屬性比較資源的最後修改時間(Last-Modified)和該值If-Modified-Since進行比較,匹配成功,則命中緩存,返回304,不然返回 資源,狀態碼爲 200,並更新緩存時間。

強制緩存

Expires

Expires 是 http1.0 的規範,它的值是一個絕對時間的GMT格式的時間字符串。這個時間表明的該資源的失效時間,若是在該時間以前請求的話,則都是從緩存裏面讀取的。若是服務端和客戶端時區不一致會致使判斷不許確。

Cache-Control

Cache-Control 是 http1.1 的規範,它是利用該字段 max-age 值進行判斷的。該值是一個相對時間,好比 Cache-Control: max-age=3600 表明該資源的有效期是3600秒。除了該字段外,咱們還有以下字段能夠設置:

no-cache: 須要進行協商緩存,發送請求到服務器確認是否使用緩存。

**no-store:**禁止使用緩存,每一次都要從新請求數據。

**public:**能夠被全部的用戶緩存,包括終端用戶和 CDN 等中間代理服務器。

**private:**只能被終端用戶的瀏覽器緩存,不容許 CDN 等中繼緩存服務器對其緩存。

配置緩存

location ~* \.(css|js|png|jpg|jpeg|gif|gz|svg|mp4|mp3|ogg|ogv|webm|htc|xml|woff)$ { # 關閉訪問日誌記錄 access_log off; # 強緩存,時間爲一年,瀏覽器和 cdn 中間件能夠緩存 add_header Cache-Control "max-age=31536000"; } 

推薦資料

推薦:值組詞

相關文章
相關標籤/搜索