天天看點

高可用架構(10)-Hystrix隔離政策、Command及資源池大小控制(下)3 command線程池4 coreSize5 queueSizeRejectionThreshold6isolation.semaphore.maxConcurrentRequests

3 command線程池

ThreadPoolKey代表了一個HystrixThreadPool,用來進行統一監控,統計,緩存

高可用架構(10)-Hystrix隔離政策、Command及資源池大小控制(下)3 command線程池4 coreSize5 queueSizeRejectionThreshold6isolation.semaphore.maxConcurrentRequests

預設的threadpool key就是command group名稱

高可用架構(10)-Hystrix隔離政策、Command及資源池大小控制(下)3 command線程池4 coreSize5 queueSizeRejectionThreshold6isolation.semaphore.maxConcurrentRequests

每個command都會跟它的ThreadPoolKey對應的ThreadPool綁定

如果不想直接用command group,也可以手動設定thread pool name

public CommandHelloWorld(String name) {
    super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"))
            .andCommandKey(HystrixCommandKey.Factory.asKey("HelloWorld"))
            .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("HelloWorldPool")));
    this.name = name;
}      

command threadpool => command group => command key

command key

高可用架構(10)-Hystrix隔離政策、Command及資源池大小控制(下)3 command線程池4 coreSize5 queueSizeRejectionThreshold6isolation.semaphore.maxConcurrentRequests
  • 代表了一類command,代表底層的依賴服務的一個接口
  • command group
高可用架構(10)-Hystrix隔離政策、Command及資源池大小控制(下)3 command線程池4 coreSize5 queueSizeRejectionThreshold6isolation.semaphore.maxConcurrentRequests

代表了某一個底層的依賴服務,合理,一個依賴服務可能會暴露出來多個接口,每個接口就是一個command key

在邏輯上去組織起來一堆command key的調用,統計資訊,成功次數,timeout逾時次數,失敗次數,可以看到某一個服務整體的一些通路情況

推薦是根據一個服務去劃分出一個線程池,command key預設都是屬于同一個線程池的

比如說你以一個服務為粒度,估算出來這個服務每秒的所有接口加起來的整體QPS在100左右

你調用那個服務的目前服務,部署了10個服務執行個體,每個服務執行個體上,其實用這個command group對應這個服務,給一個線程池,量大概在10個左右,就可以了,你對整個服務的整體的通路QPS大概在每秒100左右

一般來說,command group是用來在邏輯上組合一堆command的

舉個例子,對于一個服務中的某個功能子產品來說,希望将這個功能子產品内的所有command放在一個group中,那麼在監控和報警的時候可以放一起看

command group,對應了一個服務,但是這個服務暴露出來的幾個接口,通路量很不一樣,差異非常之大

你可能就希望在這個服務command group内部,包含的對應多個接口的command key,做一些細粒度的資源隔離

對同一個服務的不同接口,都使用不同的線程池

command key -> command group

command key -> 自己的threadpool key      

邏輯上來說,多個command key屬于一個command group,在做統計的時候,會放在一起統計

每個command key有自己的線程池,每個接口有自己的線程池,去做資源隔離和限流

但對于thread pool資源隔離來說,可能是希望能夠拆分的更加一緻一些,比如在一個功能子產品内,對不同的請求可以使用不同的thread pool

command group一般來說,可以是對應一個服務,多個command key對應這個服務的多個接口,多個接口的調用共享同一個線程池

如果說你的command key,要用自己的線程池,可以定義自己的threadpool key,就ok了

4 coreSize

設定線程池的大小,預設是10

HystrixThreadPoolProperties.Setter()
                           .withCoreSize(int value)      

一般來說,用這個預設的10個線程大小就夠了

5 queueSizeRejectionThreshold

控制queue滿後reject的threshold,因為maxQueueSize不允許熱修改,是以提供這個參數可以熱修改,控制隊列的最大值

HystrixCommand在送出到線程池之前,其實會先進入一個隊列中,這個隊列滿了之後,才會reject

預設值是5

HystrixThreadPoolProperties.Setter()
   .withQueueSizeRejectionThreshold(int value)      

線程池+queue的工作原理

高可用架構(10)-Hystrix隔離政策、Command及資源池大小控制(下)3 command線程池4 coreSize5 queueSizeRejectionThreshold6isolation.semaphore.maxConcurrentRequests

6isolation.semaphore.maxConcurrentRequests

設定使用SEMAPHORE隔離政策的時候,允許通路的最大并發量,超過這個最大并發量,請求直接被reject

這個并發量的設定,跟線程池大小的設定,應該是類似的

但是基于信号量的話,性能會好很多,而且hystrix架構本身的開銷會小很多

預設值是10,設定的小一些,否則因為信号量是基于調用線程去執行command的,而且不能從timeout中抽離,是以一旦設定的太大,而且有延時發生,可能瞬間導緻tomcat本身的線程資源本占滿

高可用架構(10)-Hystrix隔離政策、Command及資源池大小控制(下)3 command線程池4 coreSize5 queueSizeRejectionThreshold6isolation.semaphore.maxConcurrentRequests