微服務神經元(Neural)

Java高階架構老王發表於2019-04-18


微服務架構中的神經組織,主要為分散式架構提供了叢集容錯的三大利刃:限流、降級和熔斷。並同時提供了SPI、過濾器、JWT、重試機制、外掛機制。此外還提供了很多小的黑科技(如:IP黑白名單、UUID加強版、Snowflake和大併發時間戳獲取等)。

Features

  • 分散式限流(Limiter
    • 致力於分散式服務呼叫的流量控制,可以在服務之間呼叫和服務閘道器中進行限流!
  • 服務降級(Degrade
    • 致力於提供分散式的服務降級開關!
  • 個性化重試(Retryer
    • 致力於打造更加智慧的重試機制,帶你見證重試AI!
  • 服務鑑權(Auth
    • 致力於保證每次分散式呼叫鑑定,可在服務註冊、訂閱及呼叫環節進行服務鑑權!
  • 鏈路追蹤(Trace
    • 致力於為微服務架構提供鏈路追蹤的埋點!
  • 黑科技
    • Perf:效能測試神器,可以用於為單個方法或程式碼塊進行效能測試
    • NUUID:UUID擴充套件版,提供更豐富的UUID生產規則
    • Filter:基於責任鏈模式的過濾器
    • IPFilter:IP黑白名單過濾器
    • Snowflake:基於Snowflake演算法的分散式ID生成器
    • SystemClock:解決大併發場景下獲取時間戳時的效能問題

1 NPI

1.1 JDK中SPI缺陷

  • JDK標準的SPI會一次性例項化擴充套件點所有實現,如果有擴充套件實現初始化很耗時,但如果沒用上也載入,會很浪費資源
  • 不支援擴充套件點的IoC和AOP
  • 不支援實現排序
  • 不支援實現類分組
  • 不支援單例/多例的選擇

1.2 NPI功能特性

  • 支援自定義實現類為單例/多例
  • 支援設定預設的實現類
  • 支援實現類order排序
  • 支援實現類定義特徵屬性category,用於區分多維度的不同類別
  • 支援根據category屬性值來搜尋實現類
  • 支援自動掃描實現類
  • 支援手動新增實現類
  • 支援獲取所有實現類
  • 支援只建立所需實現類,解決JDK原生的全量方式
  • 支援自定義ClassLoader來載入class

TODO:需要實現對擴充套件點IoC和AOP的支援,一個擴充套件點可以直接setter注入其它擴充套件點。

1.3 使用方式

第一步:定義介面

@NPI
public interface IDemo {}
複製程式碼

第二步:定義介面實現類

@Extension("demo1")
public class Demo1Impl implements IDemo {}

@Extension("demo2")
public class Demo2Impl implements IDemo {}</pre>
複製程式碼

第三步:使用介面全路徑(包名+類名)建立介面資原始檔

src/main/resources/META-INF/neural/io.neural.demo.IDemo

第四步:在介面資原始檔中寫入實現類全路徑(包名+類名)

io.neural.demo.Demo1Impl
io.neural.demo.Demo2Impl</pre>
複製程式碼

第五步:使用ExtensionLoader來獲取介面實現類

public class Demo{
 public static void main(String[] args){
 IDemo demo1 =ExtensionLoader.getLoader(IDemo.class).getExtension("demo1");
 IDemo demo2 =ExtensionLoader.getLoader(IDemo.class).getExtension("demo2"); 
 }
}</pre>
複製程式碼

2 限流(Limiter)

在分散式架構中,限流的場景主要分為兩種:injvm模式和cluster模式。

2.1 injvm模式

2.1.1 併發量(Concurrency)

使用JDK中的訊號量(Semaphore)進行控制。

public class Test{
 public static void main(String[] args){
 Semaphore semaphore = new Semaphore(10,true);
 semaphore.acquire();
 //do something here
 semaphore.release();
 }
}</pre>
複製程式碼

2.1.2 速率控制(Rate)

使用Google的Guava中的限速器(RateLimiter)進行控制。

public class Test{
 public static void main(String[] args){
 RateLimiter limiter = RateLimiter.create(10.0); // 每秒不超過10個任務被提交
 limiter.acquire(); // 請求RateLimite
 }
}</pre>
複製程式碼

2.2 cluster模式(待完成)

分散式限流主要適用於保護叢集的安全或者用於嚴格控制使用者的請求量(API經濟)。

2.3 限制瞬時併發數

  • 定義:瞬時併發數,系統同時處理的請求/事務數量
  • 優點:這個演算法能夠實現控制併發數的效果
  • 缺點:使用場景比較單一,一般用來對入流量進行控制

2.4 限制時間窗最大請求數

  • 定義:時間窗最大請求數,指定的時間範圍內允許的最大請求數
  • 優點:這個演算法能夠滿足絕大多數的流控需求,通過時間窗最大請求數可以直接換算出最大的QPS(QPS = 請求數/時間窗)
  • 缺點:這種方式可能會出現流量不平滑的情況,時間窗內一小段流量佔位元別大

2.5 令牌桶

演算法描述

  • 假如使用者配置的平均傳送速率為r,則每隔1/r秒一個令牌被加入到桶中
  • 假設桶中最多可以存放b個令牌。如果令牌到達時令牌桶已經滿了,那麼這個令牌會被丟棄
  • 當流量以速率v進入,從桶中以速率v取令牌,拿到令牌的流量通過,拿不到令牌流量不通過,執行熔斷邏輯

屬性

  • 長期來看,符合流量的速率是受到令牌新增速率的影響,被穩定為:r
  • 因為令牌桶有一定的儲存量,可以抵擋一定的流量突發情況
    • M是以位元組/秒為單位的最大可能傳輸速率。 M>r
    • T max = b/(M-r) 承受最大傳輸速率的時間
    • B max = T max * M 承受最大傳輸速率的時間內傳輸的流量

優點:流量比較平滑,並且可以抵擋一定的流量突發情況

3 熔斷(CircuitBreaker)

在分散式架構中,熔斷的場景主要分為兩種:injvm模式和cluster模式。

3.1事件統計熔斷器(EventCountCircuitBreaker)

在指定時間週期內根據事件發生的次數來實現精簡版熔斷器。如10秒之內觸發5次事件,則進行熔斷。

3.2 門限熔斷器(ThresholdCircuitBreaker)

TODO

4 降級(Degrade)(待完成)

服務降級是指當伺服器壓力劇增時,根據當前業務情況及流量對一些服務和頁面有策略的降級,以此緩解了伺服器資源壓力,以保證核心任務的正常執行,同時也保證了部分甚至大部分客戶得到正確響應。

4.1 管理方式

4.1.1 直接管理方式:運維人員可以指定哪些模組降級

當伺服器檢測到壓力增大,伺服器監測自動傳送通知給運維人員,運維人員根據自己或相關人員判斷後通過配置平臺設定當前執行等級來降級。降級首先可以對非核心業務進行介面降級。如果效果不顯著,開始對一些頁面進行降級,以此保證核心功能的正常執行。

4.1.2 分級管理方式:運維人員無需關心業務細節,直接按級別降低即可

業務確定好對應業務的優先順序別,指定好分級降級方案。當伺服器檢測到壓力增大,服務檢測自動傳送通知給運維人員。運維人員根據情況選擇執行等級。

5 重試(Retryer)

5.1 重試策略

5.1.1 塊策略(BlockStrategy)

使當前執行緒使用Thread.sleep()的方式進行休眠重試。

5.1.2 停止策略(StopStrategy)

  • NeverStopStrategy:從不停止策略
  • StopAfterAttemptStrategy:嘗試後停止策略
  • StopAfterDelayStrategy:延遲後停止策略

5.1.3 等待策略(WaitStrategy)

  • FixedWaitStrategy:固定休眠時間等待策略
  • RandomWaitStrategy:隨機休眠時間等待策略,支援設定隨機休眠時間的下限值(minmum)與上限值(maxmum)
  • IncrementingWaitStrategy:定長遞增休眠時間等待策略
  • ExponentialWaitStrategy:指數函式(2^x,其中x表示嘗試次數)遞增休眠時間等待策略。支援設定休眠時間的上限值(maximumWait)
  • FibonacciWaitStrategy:斐波那契數列遞增休眠時間等待策略。支援設定休眠時間的上限值(maximumWait)
  • CompositeWaitStrategy:複合等待策略,即支援以上等待策略的組合計算休眠時間,最終休眠時間是以上策略中休眠時間之和
  • ExceptionWaitStrategy:異常等待策略

5.2 指定結果重試

retryIfResult(Predicate< V> resultPredicate):設定重試不滿足條件的結果

eg:如果返回結果為空則重試:retryIfResult(Predicates.< Boolean>isNull())

5.3 指定異常重試

  • retryIfException():重試所有異常
  • retryIfRuntimeException():重試執行時異常
  • retryIfExceptionOfType(Class<? extends Throwable> exceptionClass):重試指定型別異常
  • retryIfException(Predicate< Throwable> exceptionPredicate) :自定義過濾後的異常重試

5.4 重試監聽器(RetryListener)

withRetryListener(RetryListener listener):新增重試監聽器

5.5 嘗試時間限制器(AttemptTimeLimiter)

withAttemptTimeLimiter(AttemptTimeLimiter< V> attemptTimeLimiter):新增嘗試時間限制器

6 JWT(JSON Web Token)

功能來源於java-jwt專案,但有一定的調整,後續會繼續簡化。

7 過濾器(Filter)

基於@NPI擴充套件方式和責任鏈模式實現的過濾器機制。

8 黑科技(Micro)

  • Perf:效能測試工具
  • IPFilter:IP黑白名單過濾器
  • SystemClock:解決大併發場景中獲取System.currentTimeMillis()的效能問題
  • Snowflake:基於Snowflake演算法實現的高效能Long型ID生成器。理論QPS > 400w/s
  • NUUID:UUID擴充套件版。支援36/32/22/19位的UUID生成方式(不犧牲精度),支援犧牲一定精度後的15位超短UUID


相關文章