1. 程式人生 > >Spring Boot 利用 nginx 實現生產環境的偽熱更新

Spring Boot 利用 nginx 實現生產環境的偽熱更新

當我們在伺服器部署Java程式,特別是使用了 Spring Boot 生成單一 Jar 檔案部署的時候,單一檔案為我們開發單來的極大的便利性,保障程式的完整性。但同時對我們修改程式中的任何一處都帶來重啟服務的麻煩。如何解決這個問題呢?

測試用程式碼 github 下載

1 問題分析

為了能夠解決這個問題,我們來分析下,為什麼要重啟服務,因為 Jar 中的內容發生了改變,大部分應用程式都載入了記憶體中,需要重新啟動服務才能使用新的內容生效。實際上就是修改前訪問的老版本的,修改後訪問了新版本。我們使用 nginx 能夠很好的解決這個問題。

2 nginx 解決方案

nginx 中使用 upstream

負載均衡機制實現熱部署,也叫灰度釋出,即在不停止使用者訪問的前提下進行系統更新。

2.1 nginx upstream 分發策略

upstream 機制使得 nginx 以反向代理的方式執行,因此Nginx接受客戶端的請求,並根據客戶端的請求,Nginx選擇合適的後端伺服器來處理改請求。

  1. 輪詢
    每個請求按時間順序逐一分配到不同的後端伺服器,如果後端伺服器down掉,會自動剔除;
    upstream hotstart{ server 127.0.0.1:8085; server 127.0.0.1:8086; }

  2. 權重
    指定輪詢機率,weight和訪問比率成正比,用於後端伺服器效能不均的情況;

    upstream hotstart{ server 127.0.0.1:8085 weight=2; server 127.0.0.1:8086 weight=1; }

  3. 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 資料夾之外使用域名獨立訪問。也可以理解為 動靜分離

關聯閱讀