大家好,我是哪吒。
本系列為SpringCloud微服務系列,先從微服務的入口Nginx開始學習,讀哪吒程式設計,品技術人生。
最開始接觸Java語言的時候,我寫的第一個專案是圖書管理系統,當時是用JSP+servlet寫的,感覺很吊的樣子,全班領先水平。
慢慢的變成了JSP+SSM架構。
到現在單體架構最流行的SpringBoot+Vue。
但是,隨著業務量的不斷增大,你會發現,這些單體架構,已經無法滿足資料日益膨脹的今天,動不動就幾萬、幾十萬的QPS,我記得當初200QPS,我就覺得挺嚇人了。
為了解決效能問題,慢慢的微服務SpringCloud架構浮出水面,微服務的核心理念是將應用細粒化,將單一應用拆分成若干個小應用,每個小應用提供單一的業務功能,獨立部署,服務之間相互呼叫,降低程式耦合度,解決單臺伺服器宕機的問題。
微服務提供了:
注:本章的重點是Nginx,微服務其它元件就不畫了。
Nginx是俄羅斯人Igor Sysoev編寫的一款高效能 HTTP 和反向代理伺服器。Nginx選擇了epoll和kqueue作為網路I/O 模型,在高連線並行的情況下,Nginx是Apache伺服器不錯的替代品,它能夠支援高達50000個並行連線數的響應,執行穩定,且記憶體、CPU等系統資源消耗非常低。
正則匹配格式,必須以~開頭,比如server_name ~^www\d+\.nzbc\.com$;
。如果沒有~開頭,則Nginx會判定為完整匹配,在邏輯上,需要新增^和$錨定符號。正則匹配格式中.為正則元字元,需要通過反斜線進行跳脫,如果正在表示式中包含{},需要用雙引號參照起來,避免報錯。
正向代理伺服器一般位於使用者和伺服器之間,使用者通過正向代理伺服器存取應用伺服器獲取資源。
最常見的例子就是,我們存取一個外國網站,該網站無法在國內直接存取,但是可以通過代理伺服器存取,也就是說,使用者向正向代理伺服器傳送一個請求並指定目標,然後正向代理伺服器向目標伺服器(外國網站)轉交請求並將獲得的內容返回給使用者。
正向代理伺服器,代理的是使用者端,去和伺服器端互動。
反向代理伺服器一般位於使用者和伺服器之間,使用者存取反向代理伺服器獲取應用伺服器資源,使用者不知道應用伺服器的地址,是由代理伺服器轉發的,有降低網路和伺服器的負載,提高存取效率的作用。
反向代理伺服器,代理的是伺服器端,去和使用者端互動。
Nginx就是一款高效能的反向代理伺服器。
先說結論,LVS解決了Nginx單機效能瓶頸的問題。
LVS主要用於多伺服器負載均衡,工作在網路的第四層,可以實現高效能、高可用的伺服器叢集技術,採用同步請求轉發的策略。
LVS支援的並行量要比Nginx高,可以配合keepalived使用,將Nginx作為LVS的節點機器,因為Nginx在網路的第七層,功能上肯定強於LVS。
使用者通過Nginx存取應用伺服器,應用伺服器直接將資料返回給機房路由,返回時不走Nginx了,降低了Nginx的效能消耗。
預設使用輪詢方式,逐一轉發存取,這種情況適合無狀態請求,對談無法保持,可以通過基於使用者端實現對談保持。
對談保持方式:
(1)基於session實現:
session用於儲存使用者端使用者資訊,一般不在伺服器儲存session,可以通過SpringSession將session儲存到一個Redis伺服器中,再次存取時,可以到Redis伺服器中獲取session,實現session共用。
(2)基於cookie實現,無狀態的對談保持方式:
使用者端存取時,先到許可權校驗伺服器校驗許可權,生成一個cookie,並進行加密,只有伺服器能解密,使用者端沒密碼無法解密,使用者端攜帶此cookie再次存取應用伺服器,應用伺服器進行解密校驗,完成無狀態的對談保持。
通過upstream
進行權重的定義。
修改組態檔後,需要通過systemctl reload nginx
命令重啟Nginx。
nginx.conf設定如下
http{
upstream httpnz {
server 192.168.66.1 weight=1 down;
server 192.168.66.2 weight=5 backup;
server 192.168.66.3 weight=10;
}
server{
listen 80;
server_name nzbc;
location / {
proxy_pass http://httpnz;
}
error_page 500.html;
location = /500.html{
root html;
}
}
}
每個請求按存取ip的hash結果分配,對映到固定某一臺的伺服器,會導致負載均衡不平衡。
當此應用伺服器宕機後,session會丟失,再次發起請求時,會重新固定存取另一臺正常的應用伺服器,並實現對談保持。
最少連線存取。
根據存取的url轉發請求,定向流量轉發。
每個請求按存取url的hash結果分配,對映到固定的某一臺伺服器,對談無法保持。
一般在獲取本地資源時使用(且本地資源不在同一臺伺服器上),比如通過地址1獲取圖片資源、通過地址2獲取pdf協定資源。
根據伺服器響應時間轉發請求。
最常用的負載均衡策略是設定權重,其它的形式,不是很常用。
ip_hash、least_conn、url_hash、fair
,這幾種形式無法實現動態Nginx上下線(新增或減少Nginx伺服器),而且還會造成流量傾斜的問題,如果瞬時流量比較爆炸的時候,會將某個伺服器直接幹蹦。
動靜分離的最終目的是將獲取靜態資源和動態資源分離開,提升伺服器效能和高可用性。
設定靜態資源,nginx.conf設定如下
http{
upstream httpnz {
server 192.168.66.1 weight=1 down;
server 192.168.66.2 weight=5 backup;
server 192.168.66.3 weight=10;
}
server{
listen 80;
server_name nzbc;
location / {
proxy_pass http://httpnz;
}
location ~*/(js/img/css) {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html{
root html;
}
}
}
URLRewrite是實現URL重寫的關鍵指令,根據regex (正規表示式)部分內容,進行重定向。
flag標記說明:
設定URLRewrite,nginx.conf設定如下
http{
upstream httpnz {
server 192.168.66.1 weight=1 down;
server 192.168.66.2 weight=5 backup;
server 192.168.66.3 weight=10;
}
server{
listen 80;
server_name nzbc;
location / {
rewrite ^/([0-9]+).html$ /index.jsp?pageNum=$1 break;
proxy_pass http://httpnz;
}
location ~*/(js/img/css) {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html{
root html;
}
}
}