1. 程式人生 > >分散式服務框架原理與實踐

分散式服務框架原理與實踐

傳統垂直應用架構:MVC架構(Spring+Struts+Hibernate/iBatis+Tomcat)、LAMP架構(linux+Apache+PHP+MySQL)
    MVC 
        1.檢視展示層
        2.排程控制層:接受請求,呼叫相應模型元件處理請求,呼叫相應檢視顯示模型的資料
        3.應用模型層:應用程式主體部分,模型代表了業務資料和業務執行邏輯
    標準MVC不包含資料訪問層,實際開發中使用ORM

    業務組網:小規模應用通常做雙熱機,服務端監聽浮動IP,通過Watch 
    Dog監測應用程序,判斷應用宕機後切換到備用機中然後嘗試重新拉起主機。

    在高併發、大流量應用中,需要做叢集通過 F5等負載均衡器做7層負載均衡,
    後端做對等叢集部署。

缺點:1.維護成本變高,部署效率降低,某個功能(編譯、測試)出錯,需要重新打包
     2.團隊效率差,部分公共功能重複開發
     3.系統可靠性變差,某個節點故障會導致分攤到其它節點的流量陡增,引起“雪崩效應”
       垂直框架將所有模組部署到一個程序中,某個應用介面故障,導致整個節點宕機,
       由於對等叢集部署,因此其它節點也有類似問題,宕機可能此起彼伏,嚴重影響業務執行
     4.維護與定製困難,業務程式碼不斷膨脹,功能複雜,無法拆分,程式碼修改一發動全身。
     5.新功能上線週期變長  一是公共API變更  二是新特性無法獨立部署

RPC  remote procedure call 遠端服務呼叫
    負責遮蔽底層傳輸方式(TCP,UPD)、序列化方式(XML,JSON,二進位制)和通訊細節。

微服務(MSA)
    特徵: 1.原子服務,高內聚低耦合,專注於做一件事情
           2.高密度部署:重要的服務可以獨立程序部署,非核心服務可以獨立打包,合設到一個程序中
            物理機可以一臺機器多個服務例項程序,雲部署可以利用Docker實現容器級部署,提高利用率
           3.敏捷交付:小團隊負責整個生命週期支援!
           4.微自治:服務足夠小,功能單一,可以獨立打包部署升級回滾彈性伸縮,不依賴其它服務,
                區域性自治。實現

橫向:分角色拆分,客戶域,產品域,訂單域
縱向:將系統公共模組拆分出來,即服務,然後業務呼叫服務完成事務
      前臺一個叢集,service一個,資料訪問服務一個  獨立叢集

服務治理
    1.生命週期管理,服務上線隨意。下線困難,上線審批測試釋出,服務下線通知機制需要規範化
    2.服務容量規劃:
    3.執行期治理:核心服務流量壓力大,非核心服務採取降級、限流。資料庫方面,可以調大服務呼叫超時
       時間保證成功率。
    4.服務安全:敏感資料服務化後,如何對消費者授權,防止非法資料訪問,以及不同消費者不同許可權等

SOA服務治理週期: 
    1.計劃:確定服務治理的重點。
    2.定義:定義服務治理模型。
    3.啟用:實現並實施治理模型。
    4.度量:根據實施效果,改進治理模型。

Dubbo工作原理   註冊中心使用Zookeeper
    1.輕量級Java容器通過main函式初始化Spring上下文,根據服務提供者配置的XML檔案將服務按照指定協
      議釋出完成服務初始化工作。
    2.服務提供者根據配置服務註冊中心地址連結服務註冊中心,將服務提供者資訊釋出到服務註冊中心。
    3.消費者根據服務消費者XML配置檔案的服務引用資訊,連結註冊中心,獲取指定服務地址等路由資訊。
    4.服務註冊中心根據服務訂閱關係,動態向指定消費者推送服務地址訊息。
    5.消費者呼叫遠端服務時,根據路由策略,從本地快取伺服器地址列表選出一個服務提供者,然後根據
      協議型別建立鏈路,跨程序呼叫服務提供者(非本地路由優先策略時)。

主要質量屬性如下:
    1.連通性,
            ①註冊中心負責服務地址註冊、查詢,相當於目錄服務,不轉發請求,壓力小
            ②監控中心負責統計服務呼叫次數,時間等,統計彙總後定時傳送到監控中心伺服器
            ③服務消費者向註冊中心獲取服務提供者地址列表,並根據負載演算法直接呼叫提供者,
             同時彙報呼叫時間到監控中心。
            ④註冊中心、服務提供者、消費者之間為長連線,監控中心除外
            ⑤註冊中心通過長連線感知服務提供者存在,服務宕機,立刻通知消費者
            ⑥註冊中心、監控中心宕機,不影響已執行的提供者和消費者,消費者有快取服務者地址
            ⑦註冊中心、監控中心可選,服務、消費者可以直連。
    2.健壯性
            ①監控中心宕機不影響使用,只是丟掉部分取樣資料
            ②註冊中心資料庫宕機,註冊中心仍能夠通過快取提供服務列表查詢,但不能註冊新服務
            ③註冊中心對等叢集,任一臺宕機,自動切換另外一臺
            ④註冊中心全部宕機,服務提供者、消費者能通過本地快取的地址通訊
            ⑤服務提供者無狀態,任一臺宕機,不影響使用
            ⑥服務提供者全都宕機,消費者無法使用,重連等待恢復

    3.伸縮性
            ①註冊中心為對等叢集,可動態增加機器部署,客戶端自動發現新的註冊中心
            ②服務提供者提供無狀態,可動態增加機器,註冊中心將推送新的伺服器資訊給消費者

    4。擴充套件性
            ①微核心+外掛式設計,平等對待三方
            ②管道式通知方式,服務呼叫前後提供攔截面,可用於功能擴充套件,基於Filter
            ③原子化擴充套件點,最大化複用和擴充套件,擴充套件點是功能的抽象,只負責完成一件事情

淘寶HSF       註冊中心使用基於資料庫的ConfigServer
    1.配置化開發,對業務程式碼低侵入
    2.外掛管理體系:平臺與應用分開部署,執行期依賴,外部採用獨立的ClassLoader隔離,內部OSGI
    3.非同步NIO,通訊框架採用Mina封裝的TB-Remoting,支援java序列化,Hession,C與P長連線通訊
    4.靈活路由能力:客戶端軟負載,隨機、輪詢等多種路由策略,支援容災和失效恢復
    5.多協議支援WebService、Hession、PB(Protocol buffer)
    6.服務治理:支援多維度服務治理策略,包括服務監控、服務分組、限流降級、服務授權等


架構原理: service 、Filter Chain、RPC。三層

效能特徵: 
    1.高效能:同等資源TPS儘量高
    2。低資源,同等資源,服務呼叫延遲儘量低
    3.效能線性增長,增加伺服器,效能線性增長。

通訊框架

長連線:1.多訊息複用一條鏈路,省資源,短連線每次傳送訊息都要建立鏈路、發起握手認證、關閉
       2.遠端通訊是常態,呼叫時延是關鍵指標,網路時延遠遠大於一次簡單服務呼叫時不可接受的

#同步非同步關注點是你問核心資料有沒有準備好,還是核心主動通知你資料有沒有準備好。

BIO 同步阻塞IO 一個連線一個執行緒  1:1----> 使用執行緒池優化為 偽非同步 M:N  N可以大於M

NIO    同步非阻塞,提交I/O請求,然後做別的事情,定時輪詢是否完成
               同步體現在 selector 仍然要去輪循判斷 channel 是否準備好
               非阻塞體現在這個過程中處理執行緒不會一直在等待,可以去做其他的事情。

//通訊層面NIO相對BIO而言,是非同步的,所以有很多人習慣說NIO是非同步非阻塞IO
//通訊層面而言是非同步的,服務呼叫的非同步沒必然聯絡,傳統的BIO也可以實現非同步服務呼叫
//例如利用java的FutureTask來實現非同步服務呼叫。


AIO 非同步非阻塞IO  一個請求一個執行緒,Client傳資料以後做別的事情,Server完成通知Client
                                 (NonBlockingIO)
客戶端個數:IO執行緒個數    BIO     偽非同步              NIO        AIO 
                       1:1     M:N N可以大於M     M:1      M:0 系統幫忙完成
IO型別                   同步    同步            同步(IO複用)    非同步
除錯難度               簡單      簡單              複雜          複雜
可靠性                  極差     差                高            高
吞吐量                  低        中              高            高

Reactor模式
Proactor模式

鏈路有效性檢測
    心跳檢測機制
        1.TCP層心跳檢測,Keep-Alive機制,作用域整個TCP協議棧。
        2.協議層,主要存在於長連線協議中,例如SMPP協議
        3.應用層,主要由各業務產品通過約定方式定時給對方傳送心跳訊息實現。
    目的:確認當前鏈路可用。
    Netty心跳機制型別
        1.Ping-Pong型:由通訊一方定時傳送Ping訊息,對方接收到後立刻返回pong應答
        2.ping-ping:不區分心跳請求和應答,由通訊雙方約定定時向對方傳送心跳ping
          訊息,屬於雙向心跳。
    心跳策略:
        1.連續N次心跳檢測沒有收到對方pong應答訊息,或ping請求訊息,則認為鏈路已經
          發生邏輯失效,稱為心跳超時。
        2.讀取和傳送心跳訊息的時候如果發生了IO異常,說明鏈路已經失效,被認為心跳失敗
    無論是超時還是失敗,都需要關閉鏈路,由客戶端重新發起重連操作,保證鏈路恢復正常。
    Netty心跳檢測實際上利用鏈路空閒機制
        1.讀空閒,鏈路持續時間t沒有讀取到任何訊息
        2.寫空閒,
        3.讀寫空閒,   此時空閒機制是發生超時異常,關閉連線,可以定製超時實現機制。
          如:關閉鏈路,重連,警告,列印日誌等
    
斷線重連機制,當發生如下異常的時候,客戶端需要釋放資源,重新發起連線。
        1.服務因為某種原因,主動關閉連線,客戶端檢測到鏈路被正常關閉。
        2.客戶端因為宕機,強制關閉連線,客戶端檢測到鏈路被Rest掉。
        3.心跳檢測超時,客戶端主動關閉連線
        4.客戶端因為其他原因(如解碼失敗),強制關閉。
        5.網路故障,丟包,超時,單通等。
    中斷後客戶端等待INTERVAL時間重連,迴圈嘗試,直到成功。

訊息快取重發
    呼叫訊息傳送介面,訊息沒有真正寫入Socket中,而是放入NIO通訊框架的訊息
    佇列中,由Reactor執行緒掃描待發送的訊息佇列,非同步地傳送給通訊對端,若訊息
    佇列積壓資訊,此時中斷,Netty提供了在呼叫ChannelHanlerContext.write()
    的時候,返回ChannelFuture物件可以在這個上面註冊監聽Listener,在Listener
    的operationComplete()中判斷操作結果,若不成功,將其新增到重發佇列。重連
    以後根據策略,將快取佇列中訊息重發給通訊對端。

效能差的原因
    1.網路傳輸問題。傳統RPC框架或者基於RMI等方式的遠端服務,採用同步阻塞IO,
      當客戶端的併發壓力或者網路時延增大,效率降低。
    2.序列化效能差,java序列化不支援其它語言反序列化,碼流大,序列化效能差
      佔用系統資源。
    3.執行緒模型問題,執行緒資源在JVM中有限,阻塞IO導致執行緒無法及時釋放系統性能
      急劇下降。
通訊效能原則
    1.傳輸:BIO,NIO,AIO決定了通訊的效能
    2.協議:採用什麼通訊協議,公有HTTP,或私有
    3.執行緒:資料吧如何讀取,讀取以後編解碼在哪個執行緒進行,解碼後訊息如何派發
      Reactor執行緒模型不同對效能的影響也非常大。
Netty高效能的總結
    1.非同步非阻塞通訊
    2.高效IO執行緒模型:Reactor單執行緒模型、Reactor多執行緒模型、主從Reactor多執行緒模型
    3.高效能序列化框架:預設提供了Protobuf二進位制序列化框架,可以基於Netty提供的編解碼
      框架擴充套件實現。
客戶端執行緒池通常根據客戶端連線數,評估IO數,建立一個大的執行緒池NioEventLoopGroup,所有
客戶端連線公用,或者建立一個包含NioEventLoopGroup陣列,將客戶端連線按照Hash演算法分組,
所有連線均勻打散在NioEventLoopGroup中,優點是降低鎖競爭,提升處理效率。


序列化(編碼)與反序列化(解碼):物件序列化為位元組陣列,用於網路傳輸、資料持久化等
    通訊協議與序列化是解碼的,同一種協議有多種序列化方式。
    文字類:XML、JSON等   二進位制:PB(Protocol Buffer)、Thrift、Hession
    核心要求:
        1.資料結構種類,介面是否友好、簡潔、可讀性
        2.跨語言支援
        3.相容性:介面的相容(定義,輸入引數,返回值)
                 業務的邏輯相容,介面相容是前提,內部實現的業務邏輯也要向前相容
                 ,例如根據新增欄位判斷新老流程,老的業務訊息沒有攜帶擴充套件的欄位就
                 走老流程,新的走新的流程。
                 資料的相容性:包括但不限於關係型資料庫、菲關係型資料ku,表、索引等
        4.效能:
                序列化後的碼流的大小
                序列化反序列化的速度
                資源佔用主要是CPU和堆記憶體

擴充套件性設計
    Netty內建的序列化反序列化功能類http、PB、base64、JBoss、spdy等

反序列化擴充套件
    分散式服務框架中反序列化擴充套件包含兩部分
        1.業務釋出服務的時候,可以指定協議型別和承載資料的序列化方式。
        2.序列化類庫能夠以外掛的格式插入到通訊呼叫鏈中,實現序列化格式的擴充套件
          這個過程需要考慮TCP的粘包和拆包等底層相關的技術細節。
    半包處理,在反序列化之前需要保證呼叫解碼方法傳遞的是完整的資料包。否則會
    解碼失敗。

TCP的粘包和拆包
    TCP資料包的一個數據包包含兩個資料包 接收端不知道這兩個資料包的界限所
    以對於接收端來說很難處理,或者接收端收到了兩個資料包但是這兩個資料包要麼
    是不完整的,要麼就是多出來一塊。
發生TCP粘包或拆包有很多原因,現列出常見的幾點,可能不全面,歡迎補充,
    1、要傳送的資料大於TCP傳送緩衝區剩餘空間大小,將會發生拆包。
    2、待發送資料大於MSS(最大報文長度),TCP在傳輸前將進行拆包。
    3、要傳送的資料小於TCP傳送緩衝區的大小,TCP將多次寫入緩衝區的資料一次傳送‘’出去,將會發生粘包。
    4、接收資料端的應用層沒有及時讀取接收緩衝區中的資料,將發生粘包。
    等等。
    解決辦法
        1.傳送端給每個資料包新增包首部
        2、傳送端將每個資料包封裝為固定長度,不足補0。
        3、可以在資料包之間設定邊界,如添加回車、新增特殊符號。

Netty提供了4種反序列化工具類
    LineBasedFrameDecoder       回車換行解碼器
    DelimiterBasedFrameDecoder  分隔符解碼器
    FixedLengthFrameDecoder     固定長度解碼器
    LengthFieldBasedFrameDecoder  通用半包解碼器(即帶首部)

序列化擴充套件只需要繼承MessageToByteEncoder類實現encode()

序列化呼叫全域性鎖,效能下降嚴重,可以每一個執行緒聚合一個序列化反序列化類庫,避免競爭。


協議棧:不同服務在效能上適用不同協議進行傳輸,如:對接異構第三方通常用HTTP、Restful
等公有協議,對於內部不同模組之間的服務呼叫,用效能高的私有二進位制私有協議。
    WSDL:服務提供者通過這個協議向註冊中心提供服務介面描述。
    UDDI:註冊中心通過此協議釋出服務提供者的服務。
    SOAP:消費者通過此協議呼叫服務提供者,實現服務遠端呼叫。 XML序列化 
    (PS:HTTP、WebService等公有協議缺少服務描述檔案、服務註冊中心和服務訂閱釋出機制)

內部長連線採用IP地址的安全認證機制,對握手請求IP地址做合法性校驗
第三方非信任域則需要採用如:基於密匙和AES加密的使用者名稱+密碼驗證合法性,用SSL/TSL安全傳輸

若涉及到大的不相容修改,建議升級協議版本號,新增部分特性的話,可以用訊息頭的Map擴充套件


服務路由
    基於服務註冊中心的訂閱釋出
        消費者只需要知道當前系統釋出了哪些服務,而不需要知道服務具體在什麼位置,這就是
        透明化路由,例如使用Zookeeper

    負載均衡
        一.隨機
        採用隨機演算法進行負載均衡,通常在對等叢集組網中,隨機路由演算法訊息分發還是比較均勻
        缺點如下:
                 1.在一個截面上碰撞的概率比較高。
                 2.非對等叢集組網,或者配置差異較大,會導致節點負載不均勻。
        通常實現會採用JDK的Random或SecureRandom

        二.輪詢
        按公約後的權重設定輪詢比率,達到邊界以後,繼續繞接,缺點是存在慢的提供者累積請
        求問題,如:第二臺機器比較慢,沒宕機,請求調到第二臺時就卡那,久而久之所有請求
        都卡在調到第二臺上。

        三.服務呼叫時延
        消費者快取所有服務提供者的服務呼叫時延,週期性計算服務呼叫平均時延,然後計算
        每個服務提供者呼叫時延與平均時延的差值,根據差值大小動態調整權重,保證服務時
        延大的服務提供者接受更少的訊息,防止訊息堆積。特點是使所有服務提供者服務呼叫
        時延接近平均值,實現負載均衡。

        四.一致性hash
        相同引數的請求總是傳送到同一個服務提供者,當某一臺服務提供者宕機時,原本發往該
        提供者的請求,基於虛擬節點平攤到其它提供者,不會引起劇烈變動,平臺提供的預設虛
        擬節點數可通過配置引數調整。

        五.粘滯連線
        用於有狀態服務,儘可能讓客戶端總是向同一個服務提供者發起服務呼叫,除非該機器宕機
        再連線另外一臺。

    本地路由優先策略                                                                       1.injvm模式
        優先尋找本JNM內的服務提供者。

        2.innative模式
        如果物理機或虛擬機器配置好,多個應用程序會合設,消費者、服務者可能被部署
        在同一臺機器上,服務路由時優先選擇本機的服務提供者,找不到再遠端呼叫。
            首先在本程序JVM上找,找不到下一步
            選擇服務提供者IP地址與本機相同的本地合設的服務提供者,找不到下一步
            遠端找
        優點,通訊流量走本地網絡卡迴環,不佔用網路頻寬,可靠性更強,服務呼叫時延低,
        節省頻寬。

    路由規則
        條件路由規則
            1.通過IP條件表示式進行黑名單控制 例如:consumerIP!=192.168.1.1
            2.流量引導,只暴露部分服務提供者,防止其他服務提供者受影響
              providerIP=192.168.3*
            3.讀寫分離:method=find*,list*,get*,query*=>providerIP=x.x.x.*
            4.前後臺分離:app=web*=>providerIP=192.168.1.*,app=java*=>providerIP
              =192.168.2.*。
            5.灰度升級,將Web前臺應用路由到新的服務版本上:app=web*=>providerIP=
              192.168.1.*;

        指令碼路由規則
            特點是通常支援動態編譯,修改後可以實時生效,不需要重啟系統。

    路由策略定製
        應用場景如下:
        1.灰度升級,使用者需要按照業務規則進行灰度路由:例如按照使用者省份、來源終端(PC
            IOSAndroid)、手機號段、app版本等,不同使用者按照不同的規則路由到相應的叢集。
        2.伺服器故障、業務高峰期導流:將異常峰值流量導流到幾臺或一臺伺服器上,防止整個
          叢集崩潰。
        3.與業務領域強相關的非通用路由定製需求。

        擴充套件策略如下:
            1.平臺提供路由介面供使用者實現。
            2.平臺提供路由配置XML Schema定義,支援使用者擴充套件
            3.業務釋出自定義路由策略,對於通過Spring Bean方式的服務釋出,使用者定義擴充套件
              路由Bean,然後在服務提供者配置路由規則的時候,引用相關擴充套件的Bean

叢集容錯
    通訊鏈路故障
        1.一方宕機
        2.解碼失敗
        3.IO異常
        4.網路故障、交換機
        5.心跳超時
        6.FULL GC導致鏈路中斷
    服務呼叫超時
        1.IO阻塞或執行長週期任務
        2.服務端處理速度慢
        3.伺服器長時間GC,服務無應答

    服務呼叫失敗
        1.解碼失敗
        2.訊息佇列滿了,系統擁堵
        3.動態流量控制
        4.許可權校驗失敗
    容錯策略
        failover 失敗自動切換重新選路,一般重試3次
        failback 不再重試,直接將RPC異常通知給消費者
        failcache 失敗自動恢復的一種,應用場景:服務有狀態,等待一定時間重試
                  對時延不敏感的,呼叫失敗通常是鏈路不可用、流控、GC,稍等重試
        failfast  業務高峰期,非核心服務希望只調用一次,獲取異常後僅僅記錄日誌

    容錯策略擴充套件    
        1.容錯介面開放
        2.遮蔽底層細節,使用者定製簡單
        3.配置應該天生支援擴充套件,不應讓使用者擴充套件服務框架Schema

服務呼叫(解決序列呼叫效率低)  
    一、非同步呼叫 將服務呼叫時間序列優化為並行  
      同步為T = t1+t2+...    非同步為:T=Max(t1,t2,....)
                        (PS某些關鍵服務出故障,可用來防止故障擴散)
      非同步有兩種方式
            1. Future-Listener 更好,但是有侷限性
          2. Future-get

    二、並行服務呼叫
          序列服務呼叫鏈,呼叫簡單,採用並行服務呼叫來降低時延
                 多個服務邏輯上不存在互相依賴關係,可並行
              長流程業務,呼叫多個服務,時延敏感,部分不存互相依賴服務可並行
       目標:降低時延、提升系統吞吐量

    實現可採用Fork-Join,但是會開啟多個執行緒來分解任務,在伺服器框架中會導致執行緒
    上下文傳遞的變數丟失、執行緒膨脹等不可控問題,因此一般框架自己實現。get會等所有
    並行任務結束,獲取所有結果。

    泛化呼叫:
        1.泛化引用:用於客戶端沒有APi介面以及資料模型的情況
        2.泛化實現:用於服務端沒有APi介面以及資料模型的情況
    引數、返回值中所有POJO都用Map表示通常用於框架整合測試、上線後的回聲測試等

服務註冊中心
    客戶端連線註冊中心以後,需要對服務註冊中心資料進行操作CRUD介面
        增刪改查

    安全加固:鏈路安全性、資料安全性。 基於IP或usrname,pwd
            資料許可權控制。
    訂閱釋出機制
    可靠性

基於Zookeeper的服務中心設計(任一臺宕機不影響客戶端使用)
    叢集2n+1  通常n+1可用,會選舉leader根據事務id(zxid)確定同步點,
    原子廣播Zab協議:恢復模式(叢集啟動、leader崩潰)、廣播模式  
                   保證leader、server系統狀態相同。
    follower服務Client請求 ,對改變系統狀態的更新操作leader來進行提議投票
    超半數通過返回結果給Client

服務釋出設計
    釋出方式
        1.XML 程式碼零侵入、擴充套件修改方便、不需要重新編譯程式碼
        2.註解  對業務程式碼低侵入、擴充套件修改方便、但是需要重新編譯程式碼
        3.API呼叫  侵入性強、容易與某種具體服務框架繫結、需重新編譯
    灰度釋出

引數傳遞
    業務內部引數傳遞
        1.通過方法呼叫顯示傳參
        2.通過ThreadLocal   優點,不需要通過引數引用傳參。侷限性,只能在本執行緒

    服務框架內部引數傳遞
        一般採用通過訊息上下文進行訊息傳遞,例如在業務請求引數中定義Map<String,Obj>
        擴充套件引數,用於跨執行緒的引數傳遞

外部傳參
    1.服務框架自身的引數傳遞,如:分散式事務中的事務上下文資訊傳遞
    2.業務之間的引數傳遞,如:業務呼叫鏈ID的傳遞,用於唯一標識某個完成業務流程。
通訊協議支援
    最好的是使用Map<String,byte[]>     RPCContext.set(key,value);
    框架需要提供傳參介面 如 RPCContext,使用者按照規則把引數設定到平臺上下文中

PS:防止服務框架系統引數、業務引數相互覆蓋(使用的Map)
    引數應該程序生命週期管理,防止記憶體洩漏。

服務版本號
    主版本號:表示重大特性或功能改變,介面或者功能可能不相容
    此版本號:傳送了少部分功能變更,新增了一些功能。
    微版本號:主要用於修復BUG,對應常見的SP補丁包
  通常每個服務都加上版本號,不利於管理,因此將經常升級的服務單獨拿出來打包,不經常
  升級的一起打包,其中一個升級就修改全域性版本號

基於版本號的服務路由,沒找到就拋異常

服務熱升級
    1.升級的節點需要重啟,但是由於分散式服務框架具備服務的健康檢測和自動發現機制,停機
      升級的節點被自動隔離,停機並不會中斷業務。
    2.服務路由規則的定製:如果是滾動式灰度釋出,在相當長的一段時間內線上都會存在多個服
      務版本。由路由判定使用者的版本。也可以使用者配置自定義的路由規則來支援靈活路由策略。
    3.滾動升級回退機制:無論預釋出環境中測試多麼充分,真實生產環境中仍可能出BUG,此時
      需要熱回退。為了降低服務熱升級對業務的影響,同時考慮可靠性,滾動升級,分批次進行
      服務熱升級,這樣可以及時發現問題,更敏捷地進行特性交付。

OSGi 用Maven+分散式服務框架自身的服務介面匯入匯出功能解決了模組化開發和精細化依賴管理
     難題,完全可以替代OSGi

流量控制
    傳統靜態流控 :達到流控閥值後拒絕新的請求訊息接入,但是不拒絕後續的應答訊息。
    加入新機器需要手動調整,機器宕機導致分流不均,雲服務彈性伸縮特性決定了
    傳統方案行不通。

    動態配額分配製
        服務註冊中心以流量週期T為單位,動態推送每個節點分配的流控QPS,服務節點變更
        會觸發註冊中心重新計算每個節點配額,然後進行推送。
    
動態流控
    動態流控因子
        系統資源:CPU、記憶體
        應用資源:JVM堆記憶體、訊息佇列積壓率、會話積壓率(可選)

    分級流控(一級拒絕1/8  二級1/4)
        流控閥值需要支援線上修改和動態生效。

併發控制
    針對執行緒的併發執行數,本質是限制某個服務或者服務的方法過度消費,影響其它服務。
        1.針對服務提供者的全域性控制
        2.針對消費者的區域性控制

    服務端bean 的 executes引數指定數量(支援方法級別)
    客戶端         actives指定(支援方法級別)

連線控制
    服務端連線數流控<xxx:protocol name="xxx" accepts="50"/>
    客戶端   <xxx:reference interface="com.neu.xxService" connections="50"/>
    限制xxService的消費者連線數


併發和連線數控制演算法
    基於Pipeline,AOP攔截器,
    服務端:在切面攔截,從上下文獲取當前併發執行數,小於放行,計數++,大於丟擲異常,
            服務呼叫完成後,獲取上下文,併發數--
    客戶端:從上下文獲取,大於則wait();,小於則計數++,放行,若有服務呼叫完成計數--

服務降級
    需要服務釋出模型中支援降級屬性 force:return null    force:throw Exception
       <xxx:service interface="edu.neu.xxService" ref="xxService" 
           mock="force:execute Bean:xxServiceMock"/>//執行本地模擬介面實現類

容錯降級
    當服務提供者不可用時,讓消費者執行業務放通 這裡Mock介面會放在客戶端
    fail:throw Exception將異常轉義   fail:execute Bean:beanName
  在消費者配置<xxx:reference interface="edu.neu.xxService" id="xxService" 
           mock="fail:execute Bean:xxServiceMock"/>

服務優先順序排程
    服務優先順序排程策略
        1.基於執行緒排程器優先順序 根據使用者的優先順序配置策略
        2.基於優先順序佇列(不允許null元素,無界)
        3.基於加權配置
        4.基於服務遷入遷出

服務遷入遷出
    1.系統資源緊張的時候,通過服務治理Portal管理介面將低優先順序服務部分遷出,動態
    去註冊


效能KPI指標
    QPS
    呼叫時延
    呼叫成功率
    基礎資源使用情況

故障隔離
    程序級別
    vm級別
    物理機級別
    機房級別