Nginx 的 5 大應用場景,太實用了!
一、HTTP伺服器
Nginx本身也是一個靜態資源的伺服器,當只有靜態資源的時候,就可以使用Nginx來做伺服器,如果一個網站只是靜態頁面的話,那麼就可以通過這種方式來實現部署。
1、 首先在文件根目錄Docroot(/usr/local/var/www)
下建立html目錄, 然後在html中放一個test.html;
2、 配置nginx.conf
中的server
user mengday staff;
http {
server {
listen 80;
server_name localhost;
client_max_body_size 1024M;
# 預設location
location / {
root /usr/local/var/www/html;
index index.html index.htm;
}
}
}
3、訪問測試
http://localhost/
指向/usr/local/var/www/index.html
, index.html是安裝nginx自帶的htmlhttp://localhost/test.html
指向/usr/local/var/www/html/test.html
注意:如果訪問圖片出現403 Forbidden錯誤,可能是因為nginx.conf 的第一行user配置不對,預設是#user nobody;是註釋的,linux下改成user root; macos下改成user 使用者名稱 所在組; 然後重新載入配置檔案或者重啟,再試一下就可以了, 使用者名稱可以通過who am i 命令來檢視。
4、指令簡介
- server : 用於定義服務,http中可以有多個server塊
- listen : 指定伺服器偵聽請求的IP地址和埠,如果省略地址,伺服器將偵聽所有地址,如果省略埠,則使用標準埠
- server_name : 服務名稱,用於配置域名
- location : 用於配置對映路徑uri對應的配置,一個server中可以有多個location, location後面跟一個uri,可以是一個正則表示式, / 表示匹配任意路徑, 當客戶端訪問的路徑滿足這個uri時就會執行location塊裡面的程式碼
- root : 根路徑,當訪問
http://localhost/test.html
,“/test.html”會匹配到”/”uri, 找到root為/usr/local/var/www/html
,使用者訪問的資源實體地址=root + uri = /usr/local/var/www/html + /test.html=/usr/local/var/www/html/test.html
- index : 設定首頁,當只訪問
server_name
時後面不跟任何路徑是不走root直接走index指令的;如果訪問路徑中沒有指定具體的檔案,則返回index設定的資源,如果訪問http://localhost/html/
則預設返回index.html
5、location uri正則表示式
.
:匹配除換行符以外的任意字元?
:重複0次或1次+
:重複1次或更多次*
:重複0次或更多次\d
:匹配數字^
:匹配字串的開始$
:匹配字串的結束{n}
:重複n次{n,}
:重複n次或更多次[c]
:匹配單個字元c[a-z]
:匹配a-z小寫字母的任意一個(a|b|c)
: 屬線表示匹配任意一種情況,每種情況使用豎線分隔,一般使用小括號括括住,匹配符合a字元 或是b字元 或是c字元的字串\
反斜槓:用於轉義特殊字元
小括號()之間匹配的內容,可以在後面通過$1
來引用,$2
表示的是前面第二個()裡的內容。正則裡面容易讓人困惑的是\
轉義特殊字元。
二、靜態伺服器
在公司中經常會遇到靜態伺服器,通常會提供一個上傳的功能,其他應用如果需要靜態資源就從該靜態伺服器中獲取。
1、在/usr/local/var/www
下分別建立images和img目錄,分別在每個目錄下放一張test.jpg
http {
server {
listen 80;
server_name localhost;
set $doc_root /usr/local/var/www;
# 預設location
location / {
root /usr/local/var/www/html;
index index.html index.htm;
}
location ^~ /images/ {
root $doc_root;
}
location ~* \.(gif|jpg|jpeg|png|bmp|ico|swf|css|js)$ {
root $doc_root/img;
}
}
}
自定義變數使用set指令,語法 set 變數名值;引用使用變數名值;引用使用變數名; 這裡自定義了doc_root變數。
靜態伺服器location的對映一般有兩種方式:
- 使用路徑,如 /images/ 一般圖片都會放在某個圖片目錄下,
- 使用字尾,如 .jpg、.png 等字尾匹配模式
訪問http://localhost/test.jpg
會對映到 $doc_root/img
訪問http://localhost/images/test.jpg
當同一個路徑滿足多個location時,優先匹配優先順序高的location,由於^~
的優先順序大於 ~
, 所以會走/images/
對應的location
常見的location路徑對映路徑有以下幾種:
=
進行普通字元精確匹配。也就是完全匹配。^~
字首匹配。如果匹配成功,則不再匹配其他location。~
表示執行一個正則匹配,區分大小寫~*
表示執行一個正則匹配,不區分大小寫/xxx/
常規字串路徑匹配/
通用匹配,任何請求都會匹配到
location優先順序
當一個路徑匹配多個location時究竟哪個location能匹配到時有優先順序順序的,而優先順序的順序於location值的表示式型別有關,和在配置檔案中的先後順序無關。相同型別的表示式,字串長的會優先匹配。推薦:Java面試題大全
以下是按優先順序排列說明:
- 等號型別(=)的優先順序最高。一旦匹配成功,則不再查詢其他匹配項,停止搜尋。
^~
型別表示式,不屬於正則表示式。一旦匹配成功,則不再查詢其他匹配項,停止搜尋。- 正則表示式型別(
~ ~*
)的優先順序次之。如果有多個location的正則能匹配的話,則使用正則表示式最長的那個。 - 常規字串匹配型別。按字首匹配。
- / 通用匹配,如果沒有匹配到,就匹配通用的
優先順序搜尋問題:不同型別的location對映決定是否繼續向下搜尋
- 等號型別、
^~
型別:一旦匹配上就停止搜尋了,不會再匹配其他location了 - 正則表示式型別(
~ ~*
),常規字串匹配型別/xxx/
: 匹配到之後,還會繼續搜尋其他其它location,直到找到優先順序最高的,或者找到第一種情況而停止搜尋
location優先順序從高到底:
(location =
) > (location 完整路徑
) > (location ^~ 路徑
) > (location ~,~* 正則順序
) > (location 部分起始路徑
) > (/
)
location = / {
# 精確匹配/,主機名後面不能帶任何字串 /
[ configuration A ]
}
location / {
# 匹配所有以 / 開頭的請求。
# 但是如果有更長的同類型的表示式,則選擇更長的表示式。
# 如果有正則表示式可以匹配,則優先匹配正則表示式。
[ configuration B ]
}
location /documents/ {
# 匹配所有以 /documents/ 開頭的請求,匹配符合以後,還要繼續往下搜尋。
# 但是如果有更長的同類型的表示式,則選擇更長的表示式。
# 如果有正則表示式可以匹配,則優先匹配正則表示式。
[ configuration C ]
}
location ^~ /images/ {
# 匹配所有以 /images/ 開頭的表示式,如果匹配成功,則停止匹配查詢,停止搜尋。
# 所以,即便有符合的正則表示式location,也不會被使用
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
# 匹配所有以 gif jpg jpeg結尾的請求。
# 但是 以 /images/開頭的請求,將使用 Configuration D,D具有更高的優先順序
[ configuration E ]
}
location /images/ {
# 字元匹配到 /images/,還會繼續往下搜尋
[ configuration F ]
}
location = /test.htm {
root /usr/local/var/www/htm;
index index.htm;
}
注意:location的優先順序與location配置的位置無關
三、反向代理
反向代理應該是Nginx使用最多的功能了,反向代理(Reverse Proxy)方式是指以代理伺服器來接受internet上的連線請求,然後將請求轉發給內部網路上的伺服器,並將從伺服器上得到的結果返回給internet上請求連線的客戶端,此時代理伺服器對外就表現為一個反向代理伺服器。
簡單來說就是真實的伺服器不能直接被外部網路訪問,所以需要一臺代理伺服器,而代理伺服器能被外部網路訪問的同時又跟真實伺服器在同一個網路環境,當然也可能是同一臺伺服器,埠不同而已。
反向代理通過proxy_pass
指令來實現。
啟動一個Java Web專案,埠號為8081
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://localhost:8081;
proxy_set_header Host $host:$server_port;
# 設定使用者ip地址
proxy_set_header X-Forwarded-For $remote_addr;
# 當請求伺服器出錯去尋找其他伺服器
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
}
}
當我們訪問localhost的時候,就相當於訪問 localhost:8081
了
四、負載均衡
負載均衡也是Nginx常用的一個功能,負載均衡其意思就是分攤到多個操作單元上進行執行,例如Web伺服器、FTP伺服器、企業關鍵應用伺服器和其它關鍵任務伺服器等,從而共同完成工作任務。
簡單而言就是當有2臺或以上伺服器時,根據規則隨機的將請求分發到指定的伺服器上處理,負載均衡配置一般都需要同時配置反向代理,通過反向代理跳轉到負載均衡。而Nginx目前支援自帶3種負載均衡策略,還有2種常用的第三方策略。
負載均衡通過upstream指令來實現。
1. RR(round robin :輪詢 預設)
每個請求按時間順序逐一分配到不同的後端伺服器,也就是說第一次請求分配到第一臺伺服器上,第二次請求分配到第二臺伺服器上,如果只有兩臺伺服器,第三次請求繼續分配到第一臺上,這樣迴圈輪詢下去,也就是伺服器接收請求的比例是 1:1, 如果後端伺服器down掉,能自動剔除。輪詢是預設配置,不需要太多的配置
同一個專案分別使用8081和8082埠啟動專案
upstream web_servers {
server localhost:8081;
server localhost:8082;
}
server {
listen 80;
server_name localhost;
#access_log logs/host.access.log main;
location / {
proxy_pass http://web_servers;
# 必須指定Header Host
proxy_set_header Host $host:$server_port;
}
}
訪問地址仍然可以獲得響應 http://localhost/api/user/login?username=zhangsan&password=111111
,這種方式是輪詢的
2. 權重
指定輪詢機率,weight和訪問比率成正比, 也就是伺服器接收請求的比例就是各自配置的weight的比例,用於後端伺服器效能不均的情況,比如伺服器效能差點就少接收點請求,伺服器效能好點就多處理點請求。
upstream test {
server localhost:8081 weight=1;
server localhost:8082 weight=3;
server localhost:8083 weight=4 backup;
}
示例是4次請求只有一次被分配到8081上,其他3次分配到8082上。backup是指熱備,只有當8081和8082都宕機的情況下才走8083
3. ip_hash
上面的2種方式都有一個問題,那就是下一個請求來的時候請求可能分發到另外一個伺服器,當我們的程式不是無狀態的時候(採用了session儲存資料),這時候就有一個很大的很問題了,比如把登入資訊儲存到了session中,那麼跳轉到另外一臺伺服器的時候就需要重新登入了,所以很多時候我們需要一個客戶只訪問一個伺服器,那麼就需要用iphash了,iphash的每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個後端伺服器,可以解決session的問題。
upstream test {
ip_hash;
server localhost:8080;
server localhost:8081;
}
4. fair(第三方)
按後端伺服器的響應時間來分配請求,響應時間短的優先分配。這個配置是為了更快的給使用者響應
upstream backend {
fair;
server localhost:8080;
server localhost:8081;
}
5. url_hash(第三方)
按訪問url的hash結果來分配請求,使每個url定向到同一個後端伺服器,後端伺服器為快取時比較有效。在upstream中加入hash語句,server語句中不能寫入weight等其他的引數,hash_method
是使用的hash演算法
upstream backend {
hash $request_uri;
hash_method crc32;
server localhost:8080;
server localhost:8081;
}
以上5種負載均衡各自適用不同情況下使用,所以可以根據實際情況選擇使用哪種策略模式,不過fair和url_hash需要安裝第三方模組才能使用。
五、動靜分離
動靜分離是讓動態網站裡的動態網頁根據一定規則把不變的資源和經常變的資源區分開來,動靜資源做好了拆分以後,我們就可以根據靜態資源的特點將其做快取操作,這就是網站靜態化處理的核心思路。
upstream web_servers {
server localhost:8081;
server localhost:8082;
}
server {
listen 80;
server_name localhost;
set $doc_root /usr/local/var/www;
location ~* \.(gif|jpg|jpeg|png|bmp|ico|swf|css|js)$ {
root $doc_root/img;
}
location / {
proxy_pass http://web_servers;
# 必須指定Header Host
proxy_set_header Host $host:$server_port;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root $doc_root;
}
}
六、其他
1.return指令
返回http狀態碼 和 可選的第二個引數可以是重定向的URL
location /permanently/moved/url {
return 301 http://www.example.com/moved/here;
}
2. rewrite指令
重寫URI請求 rewrite,通過使用rewrite指令在請求處理期間多次修改請求URI,該指令具有一個可選引數和兩個必需引數。
第一個(必需)引數是請求URI必須匹配的正則表示式。
第二個引數是用於替換匹配URI的URI。
可選的第三個引數是可以停止進一步重寫指令的處理或傳送重定向(程式碼301或302)的標誌
location /users/ {
rewrite ^/users/(.*)$ /show?user=$1 break;
}
3. error_page指令
使用error_page指令,您可以配置NGINX返回自定義頁面以及錯誤程式碼,替換響應中的其他錯誤程式碼,或將瀏覽器重定向到其他URI。在以下示例中,error_page
指令指定要返回404頁面錯誤程式碼的頁面(/404.html)。
error_page 404 /404.html;
4. 日誌
訪問日誌:需要開啟壓縮 gzip on; 否則不生成日誌檔案,開啟log_format
、access_log
註釋
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 /usr/local/etc/nginx/logs/host.access.log main;
gzip on;
5. deny 指令
# 禁止訪問某個目錄
location ~* \.(txt|doc)${
root $doc_root;
deny all;
}
6. 內建變數
nginx的配置檔案中可以使用的內建變數以美元符$
開始,也有人叫全域性變數。其中,部分預定義的變數的值是可以改變的。
$args
:#
這個變數等於請求行中的引數,同$query_string
$content_length
:請求頭中的Content-length欄位。$content_type
:請求頭中的Content-Type欄位。$document_root
:當前請求在root指令中指定的值。$host
:請求主機頭欄位,否則為伺服器名稱。$http_user_agent
:客戶端agent資訊$http_cookie
:客戶端cookie資訊$limit_rate
:這個變數可以限制連線速率。$request_method
:客戶端請求的動作,通常為GET或POST。$remote_addr
:客戶端的IP地址。$remote_port
:客戶端的埠。$remote_user
:已經經過Auth Basic Module驗證的使用者名稱。$request_filename
:當前請求的檔案路徑,由root或alias指令與URI請求生成。$scheme
:HTTP方法(如http,https)。$server_protocol
:請求使用的協議,通常是HTTP/1.0或HTTP/1.1。$server_addr
:伺服器地址,在完成一次系統呼叫後可以確定這個值。$server_name
:伺服器名稱。$server_port
:請求到達伺服器的埠號。$request_uri
:包含請求引數的原始URI,不包含主機名,如:”/foo/bar.php?arg=baz
”。$uri
:不帶請求引數的當前URI,$uri
不包含主機名,如”/foo/bar.html
”。$document_uri
:與$uri
相同
原文連結:https://blog.csdn.net/vbirdbest/article/details/80913319
版權宣告:本文為CSDN博主「vbirdbest」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。
近期熱文推薦:
1.1,000+ 道 Java面試題及答案整理(2021最新版)
2.別在再滿屏的 if/ else 了,試試策略模式,真香!!
3.臥槽!Java 中的 xx ≠ null 是什麼新語法?
4.Spring Boot 2.5 重磅釋出,黑暗模式太炸了!
覺得不錯,別忘了隨手點贊+轉發哦!
- 有了 for (;;) 為什麼還需要 while (true) ? 到底哪個更快?
- 再見,Spring Security OAuth!!
- Spring Boot Vue Shiro 實現前後端分離、許可權控制
- Java 技術棧中介軟體優雅停機方案設計與實現全景圖
- Java 技術棧中介軟體優雅停機方案設計與實現全景圖
- JHipster:Java和JavaScript的全棧框架
- 面試官:Spring 註解 @After,@Around,@Before 的執行順序是?
- C 與Java“相愛相殺”:一個步步緊逼,一個節節敗退
- C 即將超越Java、360企業安全雲或將上線“一鍵強制下班”功能、Glibc增加面向Arm SVE優化的記憶體拷貝 ...
- 面向開發人員的映象和容器實踐指南
- 面試官:生成訂單 30 分鐘未支付,則自動取消,該怎麼實現?
- 臥槽!!IntelliJ IDEA 居然偷偷改程式碼。。
- 鑑權 5 兄弟:cookie、session、token、jwt、單點登入,終於有人說清楚了!
- 高逼格的 SQL 寫法:行行比較,別問為什麼,問就是逼格高。。
- 你見過最垃圾的程式碼長什麼樣?(來長長見識)
- 不捲了!技術團隊成員集體辭職
- 引爆全球的 Log4j2 核彈級漏洞,JNDI 到底是個什麼鬼?
- TIOBE 1月程式語言排行榜出爐:Python蟬聯冠軍,C和JAVA分列二三
- 再見,CentOS!2021/12/31 宣佈正式停服。。
- 基於 ElasticSearch 實現站內全文搜尋,寫得太好了!