第三章 分布式擴充
當我們用 top -H
指令檢視伺服器 cpu 運作狀況時,程式單機運作時很卡,表象是單機 cpu 使用率增高,記憶體 memory 占用增加,網絡帶寬使用增加,有幾個參數值得注意
-
: 使用者空間cpu使用情況(使用者态程序占比,使用者層代碼)cpu us
-
:核心空間cpu使用情況(核心态程序占比,系統調用)cpu sy
-
:1分鐘/5分鐘/15分鐘負載load平均值,跟着核數系數變化,0代表正常,1代表cpu打滿,1+代表cpu處于等待阻塞的狀态load average
-
:free 空閑記憶體,used 使用記憶體memory
Nginx 反向代理負載均衡
上一章我們看到當程式運作在單機系統時,容量有限,響應時間變長TPS (吞吐量) 上不去的問題。Nginx 反向代理的功能就是代理後端Tomcat伺服器叢集,以統一域名方式來通路。
- 單機容量問題,水準擴充
- Nginx 反向代理
- 負載均衡配置
單機容量問題,水準擴充
- Mysql 資料庫開放遠端連接配接
- 服務端水準對稱部署
- 驗證通路
注意:這次的水準擴充指的是對應用系統程式的擴充,而 Mysql 資料庫隻有一個,用來開放遠端連接配接(mysql讀寫分離、分庫分表等方法可實作 mysql 水準擴充,這裡沒讨論),服務端實作水準對稱部署,最後驗證通路。
原單機系統架構圖
改進後的Nginx系統架構圖
我們在阿裡雲就需要4台伺服器(其中1台用作資料庫,2台用作應用程式,1台用作nginx反向代理)
修改前端資源用于部署 Nginx
Nginx有三種用途:
- 使用nginx作為web伺服器(靜态資源通路)
- 使用nginx作為動靜分離伺服器
- 使用nginx作為反向動态代理伺服器(動态資源請求)
整個項目前端 H5 請求的類型有兩種,一種是靜态資源,一種是ajax請求動态資源。
- 對于
向域名ajax
請求時,miaoshaserver
會作為反向代理部署到不同nginx
項目 jar 包下;miaosha
- 而對于靜态資源 (static,HTML,CSS等) 通路域名
時,miaoshaserver/resources
會向本地磁盤請求資源(企業級應用通常使用的是NAS)nginx
部署Nginx OpenResty
使用 Nginx 的架構 OpenResty 來開發配置 Nginx,OpenResty 是基于 NGINX 和 LuaJIT 的動态Web平台。優點是可以支援lua的一些開發。
部署靜态資源請求:
- 因為我們在每個頁面中都寫上了ajax請求位址,是以現在我們要編寫一個整體的 js 檔案,裡面寫一個全局變量來代表伺服器 tomcat 端口位址,然後在每個頁面中引用該 js 檔案。
- 在
靜态資源目錄下建立static
,用來友善配置修改遠端連接配接位址,然後在每個頁面上對應修改,最後将靜态資源上傳到伺服器中gethost.js
var g_host = "localhost";
Nginx 部署
- 因為 nginx 在編譯階段需要指定很多參數來支援那些東西,對初學者不友好,是以我們選擇了安裝OpenResty
- 下載下傳好
,然後openresty
,然後解壓chmod -R 777 openresty安裝包
tar -xvzf openresty安裝包
- 進入到
目錄,開始編譯openresty
./configure
- 此時會報錯:根據報錯資訊我們需要安裝
等相關的一些操作readline、pcre、openssl
yum install pcre-devel openssl-devel gcc curl
- 官網文檔中寫清楚了我們需要的前提環境:
- 然後再次執行
,出現下圖後執行./configure
指令:make
- 下圖代表編譯完成,然後執行安裝指令
make install
- 安裝在目錄:
-
的啟動:nginx
sbin/nginx -c conf/nginx.conf
使用 nginx 作為 web 伺服器
将 nginx 指定成對應的 web 伺服器
- location節點 path :指定url映射key
- location節點内容:root 指定 location path 後對應的根路徑,index 指定預設的通路頁
-
啟動sbin/nginx -c conf/nginx.conf
- 修改配置後直接
無縫重新開機sbin/nginx -s reload
前端資源部署
- 啟動 nginx:
,預設 nginx 的端口在80端口sbin/nginx -c conf/nginx.conf
- 通路 nginx 伺服器ip位址,出現 welcome to OpenResty 則代表成功 😄
操作步驟
- 把項目目錄
中的靜态檔案上傳到 nginx 所在伺服器的resources
下:/usr/local/openresty/nginx/html/
- 上傳成功後的 html 目錄
- 修改本地 hosts 檔案,指定
的IP位址域名為nginx
miaoshaserver
- 修改 nginx 目錄下的 conf 檔案:
vim /nginx/conf/nginx.conf
upstream backend_server={
server 秒殺應用伺服器1(後端jar包位置):端口号 weight=1;
server 秒殺應用伺服器2(後端jar包位置):端口号 weight=1;
keepalive=30; # 設定的是nginx與後端伺服器之間保持長連接配接(預設不保持)
}
location /resources/ {
alias /usr/local/openresty/nginx/html/resources/;
index index.html index.htm;
}
location / {
proxy_pass http://backend_server;
# proxy_set_header Host $http_host:$proxy_port;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
- 當我們浏覽器通路
時,通路的是miaoshaserver/resources/…
目錄下的靜态資源檔案,做到H5請求靜态資源到 nginx 伺服器/usr/local/openresty/nginx/html/resources/
- 使用
無縫重新開機,指的是修改sbin/nginx -s reload
配置檔案後不需要重新開機nginx
伺服器,連接配接不會斷,隻是改變了程序号,這樣使用者就不會感覺到伺服器重新開機了。nginx
- 可以看到執行指令前後 master 程序不改變,worker 程序的程序号改變了
使用 nginx 配置動靜分離伺服器
- location 節點 path 特定 resources:靜态資源路徑
- location節點其他路徑:動态資源用
nginx 做反向代理伺服器
- 設定 upstream server(後端反向代理伺服器節點)
- 設定動态請求 location 為 proxy pass 路徑
- 開啟 tomcat access log 驗證
設定 upstream server
- 修改
配置檔案/usr/local/openresty/nginx/conf/nginx.conf
- 配置兩個應用伺服器以輪詢的方式進行,weight代表權重,設定為1代表 nginx 做反向代理的後端伺服器的輪詢是按照 1:1 的關系,也就是有一半的請求輪詢到第一台應用伺服器,有一半的請求輪詢到另一台應用伺服器。
設定動态請求 location 為 proxy pass 路徑
- 修改
配置檔案/usr/local/openresty/nginx/conf/nginx.conf
- 配置完成後,執行
無縫重新開機sbin/nginx -s reload
開啟 tomcat access log 驗證
- 開啟 tomcat access log 來驗證反向代理是否成功,雖然開啟日志要消耗一定的性能,但tomcat 内部使用的是異步日志的記錄方式,這樣就不會消耗主線程的處理時間。
- 建議在生産環境中将 tomcat access log 開啟,以便根據日志分析問題。
- 在 miaosha/目錄下面建立檔案夾tomcat,授權所有權限
,這個檔案夾作為 nginx 代理請求的日志檔案位址sudo chmod 777 tomcat/
- 在
中添加:application.properties
%h 表示遠端host位址(遠端IP位址)
%l 預設傳回-
%u 表示遠端主機user
%t 表示處理時間
%r 列印請求的方法/url
%s HTTP傳回狀态碼
%b 表示請求response的大小
%D 表示處理請求時長
- 重新開機 tomcat,重新整理網頁,發現多了一個
檔案,通過access_log
進行檢視tail -f access_log
- 表示 遠端主機為 172.31.49.160 (nginx反向代理伺服器) 的請求,GET請求,通路的是
的路徑,傳回碼 200,發送了316個位元組,處理時間 748ms/item/get?id=6
分布式擴充後的性能壓測
- 分布式擴充後,我們測試一下壓測前後的性能,設定線程數1000,循環20次,啟動時間15s進行壓測
- 請求直接打在“三合一”伺服器上:
- 請求打在 nginx 負載均衡伺服器上:
解決了單機的容量瓶頸問題,可以做水準擴充
回顧
考慮整個系統還可以優化的地方:
- miaosha.jar包從mysql本地中分離出來,涉及到區域網路的通信,而連接配接資料庫的 datasouce 采用druid資料庫連接配接池,是以延遲低。
- nginx和H5用戶端采用了tomcat長連接配接,降低了開銷。
- nginx伺服器和應用伺服器miaosha.jar采用的是短連接配接方式,可以優化。
操作步驟
- 修改
檔案/usr/local/openresty/nginx/conf/nginx.conf
- 因為 nginx 伺服器和應用伺服器的通信采用HTTP1.0協定,要配置HTTP1.1才支援長連接配接
- 無縫重新開機 nginx 伺服器,壓測性能: