前言
Nginx("engine x")是一款是由俄羅斯的程式設計師Igor Sysoev所開發高效能的 Web和 反向代理 伺服器,也是一個 IMAP/POP3/SMTP 代理伺服器。
Nginx在部署網站時,可以說是小夥伴們的首選,當然不能說全部專案都使用,對於一些小專案,直接IIS(.Net)、Tomcat(Java)等就搞定了,但對於大專案或微服務架構,Nginx肯定是少不了啦,一張圖看清Nginx有多火:
Nginx之所以招人喜愛,那是它本身效能好,支援併發量大,記憶體消耗少,配置簡單,提供功能給力,最重要是開源免費。接下來會挑重要的來說說,瞭解我的小夥伴都應該知道,我喜歡邊實操,邊說理論;走起來~~~
正文
關於安裝我就不一步一步來演示啦,如果需要詳細安裝步驟,點這裡,菜鳥教程很詳細了,接下來就重點說說平時用得比較多的功能。
以下演示是通過阿里雲伺服器演示,系統為Centos7,nginx版本為1.18.0。用到連線雲伺服器的工具為Xshell6,上傳檔案為Xftp 6.
1. 配置檔案解讀
Nginx和Redis一樣,只需簡單的檔案配置,就能輕鬆實現吊炸天的功能,所以先來了解一下配置檔案內容,不用太急著知道怎麼用,接下來在功能實操的時候還會用到。
nginx.conf檔案是經常需要配置的,我這裡安裝完成之後,該配置檔案的路徑見下圖:
檔案主要內容如下:
#指定使用者,可以不進行設定
#user nobody;
#Nginx程式,一般設定為和CPU核數一樣
worker_processes 1;
#錯誤日誌存放目錄,可以根據後面的日誌級別指定到不同目錄
error_log /var/log/nginx/error.log info;
#程式pid存放位置
pid /var/run/nginx.pid;
events {
# 單個後臺程式的最大併發數
worker_connections 1024;
}
http {
#副檔名與型別對映表,指定為當前目錄下的 mime.types
include mime.types;
#預設檔案型別
default_type application/octet-stream;
#設定日誌顯示格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#nginx訪問日誌存放位置
access_log /var/log/nginx/access.log main;
#開啟高效傳輸模式
sendfile on;
#tcp_nopush on;
#保持連線的時間,也叫超時時間
keepalive_timeout 65;
#開啟gzip壓縮
#gzip on;
#server的配置可以單獨為一個子配置檔案,避免單個配置檔案過大
server {
#配置監聽埠
listen 80;
#配置域名
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
#指定預設目錄
root html;
#預設訪問頁面
index index.html index.htm;
}
# 指定http code 配置404頁面
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#錯誤狀態碼的顯示頁面,配置後需要重啟
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
在上面配置檔案中,有幾個點需要注意:
- http配置塊中可以配置多個server塊,而每個server塊就相當於一個虛擬主機(後續會說到);
- 在server塊中可以同時包含多個location塊。
- 在http配置塊中可以使用 include 目錄/*.conf; 指定子配置檔案的位置,然後自動載入配置內容進來,避免單檔案配置過大。
2. 常用命令
這裡演示沒有配置環境變數,所以需要進入nginx的安裝目錄(/usr/local/nginx/sbin)中進行操作,進入可以執行以下命令:
-
開啟nginx
./nginx #啟動
-
停止nginx
# 方式1 ./nginx -s stop # 立即停止 # 方式2 ./nginx -s quit # 程式完成當前工作後在停止 # 方式3 killall nginx # 直接殺死程式
-
重新載入配置檔案
./nginx -s reload
-
檢視nginx的啟動情況
ps aux|grep nginx
-
檢視埠號佔用情況
netstat -tlnp # 檢視整體埠占用情況 netstat -tlnp|grep 埠號 # 檢視指定埠的佔用情況
3. 常用功能實戰
3.1 反向代理
經常有小夥伴要用google搜尋資料,被無情的拒絕了,所以只能百度;如果非要用google進行搜尋咋弄?翻牆(需要配置相關資訊),其實本質是本機電腦藉助代理伺服器轉到對應目標伺服器(小夥伴機器和代理伺服器在同一個LAN內),然後就可以間接獲取到資訊啦,這種形式就叫正向代理。如下圖:
反向代理與正向代理剛好相反,反向代理和目標伺服器在同一個LAN內,小夥伴直接訪問反向代理伺服器地址,由反向代理將請求轉發給目標服務伺服器,然後將結果返回給小夥伴。如下圖:
案例演示:
新建一個API專案,然後部署到雲伺服器上,通過nginx進行反向代理,隱藏專案的真實地址,為了執行API專案,這裡需要安裝.NetCore3.1的執行環境(不是開發就不用安裝SDK啦);
#第一步,註冊 Microsoft 金鑰和儲存庫。安裝必需的依賴項。
rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm
#第二步,安裝 .NET Core3.1 執行時,不是開發環境,就不需要安裝sdk
yum install aspnetcore-runtime-3.1
然後執行dotnet --version
命令,如果顯示對應版本就可以繼續部署程式啦;
建立一個TestWebAPI專案,將編譯之後的專案檔案通過Xftp拷貝到雲伺服器上,然後將其啟動,如下:
執行之後,由於阿里云云伺服器的安全組沒有對外開放5000埠,所以外網是訪問不了的,但可以在伺服器內通過curl命令測試站點是否啟動,如下:
我這個伺服器,80埠是對外開放的,可以訪問到的,如下:
所以現在我們通過nginx能訪問的80埠,反向代理到我們內部開啟的測試專案,即5000那個埠。nginx配置如下:
重啟nginx之後,就可以訪問啦,如下:
關鍵知識:
-
在Server塊中指定對外的埠和server_name(域名或IP);
-
配置對應Server塊中的location塊;配置location可以進行正則匹配,語法如下:
location [ = | ~ | ~* |^~] uri{ } # 匹配的路徑
=: 表示uri不包含正規表示式,要求請求字串與uri嚴格匹配,只要匹配成功立即處理該請求,不在繼續尋求匹配的規則;
~:用於表示uri中包含正規表示式,區分大小寫;
~*:用於表示uri中包含正規表示式,不區分大小寫;
^~:表示uri不包含正規表示式,找到請求字串與uri匹配度最高的location後,然後立即處理請求。
例:
實操如下:
-
在location中使用proxy_pass配置需要轉發到的目標伺服器地址;
nginx反向代理好處:
- 遮蔽目標伺服器的真實地址,相對安全性較好;
- nginx的效能好,便於配置負載均衡和動靜分離功能,合理利用伺服器資源。
- 統一入口,當做負載均衡時,不管目標伺服器怎麼擴充套件部署,呼叫者只訪問代理伺服器入口即可。
3.2 負載均衡
系統的高可用是比較重要的,所以站點會通常以叢集的方式進行部署, 但為了讓請求均勻分配到各伺服器上,則就要用到負載均衡策略啦,不管是軟體的方式還是硬體的方式都可以實現(這裡就不詳細列舉啦),大概模式如下圖:
案例演示
案例採用一個nginx做為反向代理,並通過簡單的配置實現負載均衡功能;由於裝置有限,目標伺服器採用埠不同的形式進行模擬,埠分別是5000和6000,然後在原來的專案中增加一個獲取埠的介面,用於便於案例演示,程式碼如下:
然後將編譯完成之後的專案檔案通過xFtp拷貝到雲伺服器上,然後用以不同埠的形式分別在不同終端啟動,命令如下:
另外開啟一個終端,如上圖一樣啟動專案,只是配置埠為5000開啟,這樣專案就啟動了兩個(叢集),接下來就通過配置nginx來實現負載均衡的功能。如下圖:
nginx負載均衡策略
如上演示,預設情況下,nginx的負載均衡策略為輪詢,在實際應用場景中可以根據需要配置其他策略,如下:
-
輪詢:預設就是,指每個請求按照請求順序逐一分配到不同到目標伺服器,如果目標伺服器有當機的,還能自動剔除。
-
權重(weight):通過配置權重來實現請求分配,目標伺服器配置的權重越高,被分配的請求越多。
# 其他不變,只是在每個目標伺服器後面增加權重即可 upstream testloadbalance { server 127.0.0.1:5000 weight=5; server 127.0.0.1:6000 weight=10; }
按照上面配置重啟nginx,多次請求測試,請求會更多的轉發到6000上面。
-
ip_hash:每個請求有對應的ip,通過對ip進行hash計算,根據這個結果就能訪問到指定的目標伺服器;這種方式可以保證對應客戶端固定訪問到對應的目標伺服器;
# 其他不變,只是增加一個策略進行 upstream testloadbalance { ip_hash; # 指定策略為通過ip進行hash之後轉發 server 127.0.0.1:5000; server 127.0.0.1:6000; }
-
fair:按目標伺服器的響應時間來分配請求,響應時間短的優先被分配。
關於這種模式需要額外安裝nginx-upstream-fair,然後配置一下策略即可,安裝就不具體演示,點選上面連線進入看說明;配置內容如下:
# 其他不變,只是增加一個策略進行 upstream testloadbalance { fair; # 指定策略為fair server 127.0.0.1:5000; server 127.0.0.1:6000; }
負載均衡的功能的配置是不是很簡單~~~,動動手感覺就是舒坦。
3.3 動靜分離
前後端分離開發的模式最近幾年是火的不行,在部署方面,為了提高系統效能和使用者體驗,也會將動靜分離部署,即將靜態資源(如html、js、css、圖片等)單獨部署一個站點,關於WebAPI獲取和處理資訊單獨部署為一個站點。本質還是通過location匹配規則,將匹配的請求進行不同的處理即可。
環境準備
在nginx安裝目錄下建立一個static目錄,用於存放相關靜態資源:
結構如下:
動靜分離配置
重啟nginx(或重新載入配置檔案),然後訪問看效果:
動靜分離思想就是這樣直觀,小夥伴可以根據自己的需要,定義location的匹配規則即可。
4. 其他功能
除了以上常用的功能,可能還有一些小功能也會常用到哦,比如根據http狀態碼配置指定頁面、訪問許可權控制、適配PC或移動端等,以下挑幾個平時比較常用的演示一把,如下:
-
根據狀態碼配置指定頁面
就拿平時常見的404舉例,預設可能就是簡單的頁面提示,如下:
但是對於很多企業都喜歡做自己個性化的頁面,還有一些用來做公益廣告等等;nginx配置很簡單,如下:
其他http狀態碼也可以通過上面的方式進行自定義頁面展示。
-
訪問許可權控制
為了系統安全,會針對請求增加訪問許可權控制,比如使用黑白名單的方式來進行控制,將訪問IP加入到白名單就可以訪問,加入到黑名單就不可以訪問啦,如下:
上圖是拒絕指定IP,如果是允許指定IP,可進行如下配置,如下:
location /weatherforecast/ { proxy_pass http://testloadbalance; # 這個ip是百度輸入ip檢視到的,也可以通過nginx日誌可以看 allow 223.88.45.26; }
注:如果在同一location塊中同時配置deny和allow,配置在最前面的會覆蓋下面的,如下:
location /weatherforecast/ { proxy_pass http://testloadbalance; # deny all 放在前面,就所有不能訪問,deny all 會覆蓋下面配置 #deny all; allow 223.88.45.26; # deny all 放在後面,被上面allow進行覆蓋 deny all; }
-
適配PC或移動端
現在的移動端好多都是採用H5的形式進行開發,或者是混合模式,所以也需要針對移動端部署對應的站點,那用nginx如何自動適配PC還是移動端頁面呢?
準備環境
在nginx安裝目錄中建立pcandmobile目錄,如下:
目錄裡面內容如下:
兩個index.html中的就只有一個h1標籤,分別顯示“PC端頁面”和“移動端頁面” 文字。
nginx配置
location / { root pcandmobile/pc; # 預設在pc目錄中找頁面 # 當請求頭中User-Agent中匹配如下內容時,就去mobile目錄找頁面 if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') { root pcandmobile/mobile; } index index.html; }
執行效果如下:
本質就是判斷請求頭中User-Agent,只要匹配到移動端,就去找指定移動頁面就行啦。
總結
nginx的常用功能就先說到這吧,分享的功能對於搞開發的小夥伴來說應該是隨便夠用了,如果需要深入,還得下下功夫;下次來說說如何配置高可用:主從模式、雙主模式。
一個被程式搞醜的帥小夥,關注"Code綜藝圈",跟我一起學~~~