主頁 > 後端開發 > Hystrix 配置引數全決議

Hystrix 配置引數全決議

2021-09-09 15:24:54 後端開發

前言


不久前在部門周會上分享了 Hystrix 原始碼決議之后,就無奈地背上了專家包袱,同事們都認為我對 Hystrix 很熟,我們接觸 Hystrix 更多的還是作業中的使用和配置,所以很多人一遇到 Hystrix 的配置問題就會過來問我,為了不讓他們失望,我把 Hystrix 的 配置檔案 仔細看了一遍,將有疑問的點通過翻原始碼、查官方 issue、自己實驗的方式整理了一遍,這才對 Hystrix 的配置有了一定的了解,

在了解這些配置項的程序中,我也發現了很多坑,平常我們使用中認為理所應當的值并不會讓 Hystrix 如期望作業,沒有經過斟酌就復制粘貼的配置會讓 Hystrix 永遠不會起作用,于是寫下本文,希望能幫助小伙伴們掌握 Hystrix,

HystrixCommand


配置方式

我們的配置都是基于 HystrixCommand 的,我們通過在方法上添加 @HystrixCommand 注解并配置注解的引數來實作配置,但有的時候一個類里面會有多個 Hystrix 方法,每個方法都是類似配置的話會冗余很多代碼,這時候我們可以在類上使用 @DefaultProperties 注解來給整個類的 Hystrix 方法設定一個默認值,

配置項

下面是 HystrixCommand 支持的引數,除了 commandKey/observableExecutionMode/fallbackMethod 外,都可以使用 @DefaultProperties 配置默認值,

  • commandKey:用來標識一個 Hystrix 命令,默認會取被注解的方法名,需要注意:Hystrix 里同一個鍵的唯一標識并不包括 groupKey,建議取一個獨一二無的名字,防止多個方法之間因為鍵重復而互相影響,

  • groupKey:一組 Hystrix 命令的集合, 用來統計、報告,默認取類名,可不配置,

  • threadPoolKey:用來標識一個執行緒池,如果沒設定的話會取 groupKey,很多情況下都是同一個類內的方法在共用同一個執行緒池,如果兩個共用同一執行緒池的方法上配置了同樣的屬性,在第一個方法被執行后執行緒池的屬性就固定了,所以屬性會以第一個被執行的方法上的配置為準,

  • commandProperties:與此命令相關的屬性,

  • threadPoolProperties:與執行緒池相關的屬性,

  • observableExecutionMode:當 Hystrix 命令被包裝成 RxJava 的 Observer 異步執行時,此配置指定了 Observable 被執行的模式,默認是 ObservableExecutionMode.EAGER,Observable 會在被創建后立刻執行,而 ObservableExecutionMode.EAGER模式下,則會產生一個 Observable 被 subscribe 后執行,我們常見的命令都是同步執行的,此配置項可以不配置,

  • ignoreExceptions:默認 Hystrix 在執行方法時捕獲到例外時執行回退,并統計失敗率以修改熔斷器的狀態,而被忽略的例外則會直接拋到外層,不會執行回退方法,也不會影響熔斷器的狀態,

  • raiseHystrixExceptions:當配置項包括 HystrixRuntimeException 時,所有的未被忽略的例外都會被包裝成 HystrixRuntimeException,配置其他種類的例外好像并沒有什么影響,

  • fallbackMethod:方法執行時熔斷、錯誤、超時時會執行的回退方法,需要保持此方法與 Hystrix 方法的簽名和回傳值一致,

  • defaultFallback:默認回退方法,當配置 fallbackMethod 項時此項沒有意義,另外,默認回退方法不能有引數,回傳值要與 Hystrix方法的回傳值相同,

commandProperties


配置方式

Hystrix 的命令屬性是由 @HystrixProperty 注解陣列構成的,HystrixProperty 由 name 和 value 兩個屬性,資料型別都是字串,

以下將所有的命令屬性分組來介紹,

微服務專案to    fhadmin.cn

執行緒隔離(Isolation)

  • execution.isolation.strategy: 配置請求隔離的方式,有 threadPool(執行緒池,默認)和 semaphore(信號量)兩種,信號量方式高效但配置不靈活,我們一般采用 Java 里常用的執行緒池方式,

  • execution.timeout.enabled:是否給方法執行設定超時,默認為 true,

  • execution.isolation.thread.timeoutInMilliseconds:方法執行超時時間,默認值是 1000,即 1秒,此值根據業務場景配置,

  • execution.isolation.thread.interruptOnTimeout: execution.isolation.thread.interruptOnCancel:是否在方法執行超時/被取消時中斷方法,需要注意在 JVM 中我們無法強制中斷一個執行緒,如果 Hystrix 方法里沒有處理中斷信號的邏輯,那么中斷會被忽略,

  • execution.isolation.semaphore.maxConcurrentRequests:默認值是 10,此配置項要在 execution.isolation.strategy 配置為 semaphore 時才會生效,它指定了一個 Hystrix 方法使用信號量隔離時的最大并發數,超過此并發數的請求會被拒絕,信號量隔離的配置就這么一個,也是前文說信號量隔離配置不靈活的原因,

統計器(Metrics)

滑動視窗: Hystrix 的統計器是由滑動視窗來實作的,我們可以這么來理解滑動視窗:一位乘客坐在正在行駛的列車的靠窗座位上,列車行駛的公路兩側種著一排挺拔的白楊樹,隨著列車的前進,路邊的白楊樹迅速從視窗滑過,我們用每棵樹來代表一個請求,用列車的行駛代表時間的流逝,那么,列車上的這個視窗就是一個典型的滑動視窗,這個乘客能通過視窗看到的白楊樹就是 Hystrix 要統計的資料,

: bucket 是 Hystrix 統計滑動視窗資料時的最小單位,同樣類比列車視窗,在列車速度非常快時,如果每掠過一棵樹就統計一次視窗內樹的資料,顯然開銷非常大,如果乘客將視窗分成十分,列車前進行時每掠過視窗的十分之一就統計一次資料,開銷就完全可以接受了, Hystrix 的 bucket (桶)也就是視窗 N分之一 的概念,

  • metrics.rollingStats.timeInMilliseconds:此配置項指定了視窗的大小,單位是 ms,默認值是 1000,即一個滑動視窗默認統計的是 1s 內的請求資料,

  • metrics.healthSnapshot.intervalInMilliseconds:它指定了健康資料統計器(影響 Hystrix 熔斷)中每個桶的大小,默認是 500ms,在進行統計時,Hystrix 通過 metrics.rollingStats.timeInMilliseconds / metrics.healthSnapshot.intervalInMilliseconds 計算出桶數,在視窗滑動時,每滑過一個桶的時間間隔時就統計一次當前視窗內請求的失敗率,

  • metrics.rollingStats.numBuckets:Hystrix 會將命令執行的結果型別都統計匯總到一塊,給上層應用使用或生成統計圖表,此配置項即指定了,生成統計資料流時滑動視窗應該拆分的桶數,此配置項最易跟上面的 metrics.healthSnapshot.intervalInMilliseconds 搞混,認為此項影響健康資料流的桶數, 此項默認是 10,并且需要保持此值能被 metrics.rollingStats.timeInMilliseconds 整除,

  • metrics.rollingPercentile.enabled:是否統計方法回應時間百分比,默認為 true 時,Hystrix 會統計方法執行的 1%,10%,50%,90%,99% 等比例請求的平均耗時用以生成統計圖表,

  • metrics.rollingPercentile.timeInMilliseconds:統計回應時間百分比時的視窗大小,默認為 60000,即一分鐘,

  • metrics.rollingPercentile.numBuckets:統計回應時間百分比時滑動視窗要劃分的桶用,默認為6,需要保持能被metrics.rollingPercentile.timeInMilliseconds 整除,

  • metrics.rollingPercentile.bucketSize:統計回應時間百分比時,每個滑動視窗的桶內要保留的請求數,桶內的請求超出這個值后,會覆寫最前面保存的資料,默認值為 100,在統計回應百分比配置全為默認的情況下,每個桶的時間長度為 10s = 60000ms / 6,但這 10s 內只保留最近的 100 條請求的資料,

熔斷器(Circuit Breaker)

  • circuitBreaker.enabled:是否啟用熔斷器,默認為 true;

  • circuitBreaker.forceOpen: circuitBreaker.forceClosed:是否強制啟用/關閉熔斷器,強制啟用關閉都想不到什么應用的場景,保持默認值,不配置即可,

  • circuitBreaker.requestVolumeThreshold:啟用熔斷器功能視窗時間內的最小請求數,試想如果沒有這么一個限制,我們配置了 50% 的請求失敗會打開熔斷器,視窗時間內只有 3 條請求,恰巧兩條都失敗了,那么熔斷器就被打開了,5s 內的請求都被快速失敗,此配置項的值需要根據介面的 QPS 進行計算,值太小會有誤打開熔斷器的可能,值太大超出了時間視窗內的總請求數,則熔斷永遠也不會被觸發,建議設定為 QPS * 視窗秒數 * 60%

  • circuitBreaker.errorThresholdPercentage:在通過滑動視窗獲取到當前時間段內 Hystrix 方法執行的失敗率后,就需要根據此配置來判斷是否要將熔斷器打開了, 此配置項默認值是 50,即視窗時間內超過 50% 的請求失敗后會打開熔斷器將后續請求快速失敗,

  • circuitBreaker.sleepWindowInMilliseconds:熔斷器打開后,所有的請求都會快速失敗,但何時服務恢復正常就是下一個要面對的問題,熔斷器打開時,Hystrix 會在經過一段時間后就放行一條請求,如果這條請求執行成功了,說明此時服務很可能已經恢復了正常,那么會將熔斷器關閉,如果此請求執行失敗,則認為服務依然不可用,熔斷器繼續保持打開狀態,此配置項指定了熔斷器打開后經過多長時間允許一次請求嘗試執行,默認值是 5000,

其他(Context/Fallback)

  • requestCache.enabled:是否啟用請求結果快取,默認是 true,但它并不意味著我們的每個請求都會被快取,快取請求結果和從快取中獲取結果都需要我們配置 cacheKey,并且在方法上使用 @CacheResult 注解宣告一個快取背景關系,

  • requestLog.enabled:是否啟用請求日志,默認為 true,

  • fallback.enabled:是否啟用方法回退,默認為 true 即可,

  • fallback.isolation.semaphore.maxConcurrentRequests:回退方法執行時的最大并發數,默認是10,如果大量請求的回退方法被執行時,超出此并發數的請求會拋出 REJECTED_SEMAPHORE_FALLBACK 例外,

threadPoolProperties


配置方式

執行緒池的配置也是由 HystrixProperty 陣列構成,配置方式與命令屬性一致,

配置項

  • coreSize:核心執行緒池的大小,默認值是 10,一般根據 QPS * 99% cost + redundancy count 計算得出,

  • allowMaximumSizeToDivergeFromCoreSize:是否允許執行緒池擴展到最大執行緒池數量,默認為 false;

  • maximumSize:執行緒池中執行緒的最大數量,默認值是 10,此配置項單獨配置時并不會生效,需要啟用 allowMaximumSizeToDivergeFromCoreSize項,

  • maxQueueSize:作業佇列的最大值,默認值為 -1,設定為此值時,佇列會使用 SynchronousQueue,此時其 size 為0,Hystrix 不會向佇列記憶體放作業,如果此值設定為一個正的 int 型,佇列會使用一個固定 size 的 LinkedBlockingQueue,此時在核心執行緒池內的執行緒都在忙碌時,會將作業暫時存放在此佇列內,但超出此佇列的請求依然會被拒絕,

  • queueSizeRejectionThreshold:由于 maxQueueSize 值在執行緒池被創建后就固定了大小,如果需要動態修改佇列長度的話可以設定此值,即使佇列未滿,佇列內作業達到此值時同樣會拒絕請求,此值默認是 5,所以有時候只設定了 maxQueueSize 也不會起作用,

  • keepAliveTimeMinutes:由上面的 maximumSize,我們知道,執行緒池內核心執行緒數目都在忙碌,再有新的請求到達時,執行緒池容量可以被擴充為到最大數量,等到執行緒池空閑后,多于核心數量的執行緒還會被回收,此值指定了執行緒被回收前的存活時間,默認為 2,即兩分鐘,

作業方式

Hystrix 內執行緒池的使用是基于 Java 內置執行緒池的簡單包裝,通常有以下三種狀態:

  • 如果請求量少,達不到 coreSize,通常會使用核心執行緒來執行任務,

  • 如果設定了 maxQueueSize,當請求數超過了 coreSize, 通常會把請求放到 queue 里,待核心執行緒有空閑時消費,

  • 如果 queue 長度無法存盤請求,則會創建新執行緒執行直到達到 maximumSize 最大執行緒數,多出核心執行緒數的執行緒會在空閑時回收,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/298791.html

標籤:其他

上一篇:🎮Python游戲開發,pygame模塊,Python實作消消樂小游戲🎮

下一篇:C語言 __STDC__ - C語言零基礎入門教程

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more