Spring Boot 利用 nginx 實現生產環境的偽熱更新
當我們在伺服器部署Java程式,特別是使用了 Spring Boot
生成單一 Jar 檔案部署的時候,單一檔案為我們開發單來的極大的便利性,保障程式的完整性。但同時對我們修改程式中的任何一處都帶來重啟服務的麻煩。如何解決這個問題呢?
測試用程式碼 github 下載
1 問題分析
為了能夠解決這個問題,我們來分析下,為什麼要重啟服務,因為 Jar
中的內容發生了改變,大部分應用程式都載入了記憶體中,需要重新啟動服務才能使用新的內容生效。實際上就是修改前訪問的老版本的,修改後訪問了新版本。我們使用 nginx
能夠很好的解決這個問題。
2 nginx 解決方案
在 nginx
中使用 upstream
2.1 nginx upstream 分發策略
upstream
機制使得 nginx
以反向代理的方式執行,因此Nginx接受客戶端的請求,並根據客戶端的請求,Nginx選擇合適的後端伺服器來處理改請求。
輪詢
每個請求按時間順序逐一分配到不同的後端伺服器,如果後端伺服器down掉,會自動剔除;
upstream hotstart{ server 127.0.0.1:8085; server 127.0.0.1:8086; }
權重
指定輪詢機率,weight和訪問比率成正比,用於後端伺服器效能不均的情況;upstream hotstart{ server 127.0.0.1:8085 weight=2; server 127.0.0.1:8086 weight=1; }
ip雜湊演算法
每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個後端的伺服器,可以解決session問題;upstream hotstart{ ip_hash; server 127.0.0.1:8085; server 127.0.0.1:8086; }
2.2 nginx 配置負載均衡和分發
在伺服器建立兩個一模一樣的站點分為為
- 127.0.0.1:8085
- 127.0.0.1:8086
配置 nginx.conf 檔案
注意 hotstart.fishpro.com.cn 是我配置的,你可以配置為你自己的域名
upstream hotstart{
server 127.0.0.1:8085;
server 127.0.0.1:8086;
}
server{
listen 80;
server_name hotstart.fishpro.com.cn;
location / {
proxy_pass http://hotstart;
index index.html index.htm;
}
}
執行 nignx 更新命令
>ningx -s reload
nginx 詳細配置
- weight 訪問權重
- max_fails 最大失敗次數
- fail_timeout 最大失敗等待時間
upstream hotstart{
server 127.0.0.1:8085 weight=1 max_fails=3 fail_timeout=20s;
server 127.0.0.1:8086 weight=1 max_fails=3 fail_timeout=20s;
}
server{
listen 80;
server_name hotstart.fishpro.com.cn;
location / {
proxy_pass http://hotstart;
index index.html index.htm;
}
}
編寫測試用程式碼
測試用程式碼 github 下載
執行
java -Xms256m -Xmx512m -jar hotstart-0.0.1-SNAPSHOT.jar --server.port=8085
java -Xms256m -Xmx512m -jar hotstart-0.0.1-SNAPSHOT.jar --server.port=8086
訪問站點 hotstart.fishpro.com.cn
檢視結果後,我們關閉當前檢視結果的站點 再次重新整理,我們可以看出當一個站點停止服務,nginx 則訪問另一個站點,這樣我們就可以逐個站點來實現不需要中斷使用者訪問來更新服務。
問題
多個站點如何共享會話 session
- 通過 redis 等 nosql 中介軟體實現 session 共享
- 通過配置 tomcat 服務實現
- 其他解決方案
3 其他優化點
3.1 利用 nginx 把靜態檔案獨立 jar 檔案之外
我們知道靜態檔案使用 nginx 直接提供服務則更快更穩定,所以我們構件站點的時候直接把靜態檔案包括 css、js、image 等放在 jar 資料夾之外使用域名獨立訪問。也可以理解為 動靜分離
關聯閱讀
- Spring Boot 多環境配置
- Spring Boot 自定義 Banner
- Spring Boot 配置檔案和命令列配置
- Spring Boot 利用 nginx 實現生產環境的偽熱更新