一、介紹 微服務架構中的應用優雅停機主要是指應用實例有計劃而平滑(即不產生須要處理的事故)的退出。應用服務器的停機主要分爲兩類:主動停機和被動停機,而其中主動停機和大部分的被動停機都是能夠實現優雅停機。若是應用不作優雅停機,則會帶來如下狀況:後端
•數據丟失:內存的中數據還沒有持久化至磁盤 •文件損壞:正在操做寫的文件因沒有更新完成,致使文件損壞 •請求丟失:排隊中等待處理的請求丟失 •響應丟失:成功的交易還沒來得及作出響應 •交易中斷:正在處理至中間狀態的交易被強制中斷 •服務未下線:上游服務依然還會繼續往下游服務發送消費請求 而咱們微服務的優雅升級的目標就是避免以上幾種狀況,從而避免人工干預的工做量和提高微服務架構的服務高可靠。服務器
二、使用場景 優雅停機能夠解決如下場景:架構
•KILL PID •應用意外自動退出 •使用腳本命令的方式中止應用 •優雅停機解決不了如下場景:ide
•忽然斷電 •機器物理破壞 •KILL-9 PID 或 taskkill /f /pid微服務
三、ShutdownHook Java的優雅停機一般經過註冊JDK的ShutdownHook(鉤子)來實現,當系統接收到退出指令後,首先標記系統處於退出狀態,再也不接收新的消息,而後將積壓的消息處理完,最後調用資源回收接口將資源銷燬,最後各線程退出執行。簡單的使用demo案例以下(簡單版):線程
/**設計
優雅停機處理方式cdn
@author lry **/ public class Main{blog
/**接口
啓動應用 **/ public void start(){ // 第一步:啓動應用服務……
// 第二步:註冊JDK鉤子 Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { @Override public void run() { System.out.println(「The hook running…」); //第三步:調用停機處理 stop(); } })); }
/**
中止應用 **/ public void stop(){ // 中止應用前停機處理(如:註銷服務、標記不接受請求等) } } 超時控制 一般優雅退出須要有超時控制機制,若是到達超時時間仍然沒有完成退出前的資源回收等操做,則由停機腳本直接調用KILL -9 PID的方式進行強制退出,否則可能會等待很長時間。
四、微服務優雅停機 微服務的優雅停機沒有統一的解決方案,只要抓住核心思想進行設計便可: 引流 → 擋板 → 等待停機
但在微服務架構中,咱們能夠遵照如下建議規則來設計微服務的優雅停機機制: •全部微服務應用都應該支持優雅停機 •優先註銷註冊中心註冊的服務實例 •待停機的服務應用的接入點標記拒絕服務 •上游服務支持故障轉移因優雅停機而拒絕的服務 •根據具體業務也提供適當的停機接口 微服務應用的優雅停機根據其使用者角色的不一樣,而主要分爲兩種類型:
•微服務業務應用優雅停機設計:
•微服務業務應用優雅停機設計其他各層設備的優雅停機均可從以上兩種類型進行衍生出解決方案,如:
•整個後端架構升級,則可從DNS或Nginx直接切換 •Nginx層升級,則能夠從DNS直接切換
五、使用案例 在業界開源的產品中,不少產品都使用了JDK鉤子的方式來實現優雅停機,如如下產品:
•Netty •DUBBO