自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

聊聊微服務(wù)的隔離和熔斷

企業(yè)動(dòng)態(tài)
今天來聊一聊微服務(wù)的隔離和熔斷是怎么做的, 如果你的項(xiàng)目沒有用微服務(wù),不要走開,可以看看對(duì)一個(gè)問題的解決思路。

 今天來聊一聊微服務(wù)的隔離和熔斷是怎么做的, 如果你的項(xiàng)目沒有用微服務(wù),不要走開,可以看看對(duì)一個(gè)問題的解決思路。 

按照碼農(nóng)翻身的慣例, 我們先用一個(gè)例子來拋出問題:

假設(shè)Tomcat線程池有100個(gè)線程, 每次有新的用戶請(qǐng)求過來,Tomcat就會(huì)從中找出一個(gè)空閑的線程去執(zhí)行, 拋開那些瑣碎的小細(xì)節(jié),這些請(qǐng)求其實(shí)非常簡(jiǎn)單, 無非就是這么幾件事:

1. 根據(jù)用戶ID調(diào)用用戶服務(wù), 獲取用戶對(duì)象。

2. 獲取該用戶的推薦商品

3. 獲取該用戶的積分。

4. 把這些信息組合起來,返回給瀏覽器。

有意思的是前三件事情全是HTTP調(diào)用,需要調(diào)用某個(gè)地方的所謂“微服務(wù)”。

 

有一次,線程A去執(zhí)行幾個(gè)邏輯,等它調(diào)用“推薦服務(wù)”的時(shí)候,“推薦服務(wù)”遲遲沒有返回,線程A也許很高興, 終于可以休息了!

新的用戶請(qǐng)求源源不斷地到來,線程池中越來越多的線程都在等待推薦服務(wù)返回。

很快,100個(gè)線程全部用光,Tomcat只好掛出一個(gè)牌子: “系統(tǒng)繁忙,暫停營(yíng)業(yè)。”

總之, 一個(gè)服務(wù)的出錯(cuò)竟然導(dǎo)致了整個(gè)Tomcat不可用,實(shí)在是難以忍受。

也許你會(huì)和運(yùn)維商量一下,來個(gè)簡(jiǎn)單粗暴的辦法: 給Tomcat線程池在增加100個(gè)線程兄弟, 可是這不能解決問題, 在高并發(fā)的情況下, 只要那些遠(yuǎn)程的微服務(wù)有一個(gè)阻塞,無論多少線程,很快就會(huì)被用光。

于是,你只好重啟Tomcat,毀滅這個(gè)可愛的世界,但是重啟后問題還是有可能發(fā)生。

隔離

怎么把一個(gè)微服務(wù)的故障給隔離起來呢?讓他們互不影響呢?

Netflix的程序員們想了一個(gè)點(diǎn)子, 對(duì)每個(gè)微服務(wù),都分配一個(gè)線程池,像這樣:

 

 

 

 

比如說調(diào)用“推薦服務(wù)”的時(shí)候,就會(huì)從“推薦服務(wù)線程池” (假設(shè)有5個(gè)線程)中找到一個(gè)線程執(zhí)行。如果這個(gè)HTTP系統(tǒng)調(diào)用遲遲沒有返回,那這個(gè)線程就會(huì)一直等待,新的請(qǐng)求就需用使用池中別的線程。

如果5個(gè)線程都用光了,會(huì)發(fā)生什么情況?

這很簡(jiǎn)單, 可以簡(jiǎn)單地認(rèn)為這個(gè)服務(wù)不可用了!馬上返回,絕不等待。

 

這些新的線程池,是一種隔離的手段, 一個(gè)微服務(wù)一旦出了問題,很快就會(huì)被識(shí)別出來。

熔斷器

但是上面這種方案,還是有一定的問題,如果這個(gè)推薦服務(wù)已經(jīng)不可用了,還不斷地嘗試去調(diào)用,那肯定是一種浪費(fèi)。

所以Netflix的程序員又想了一個(gè)辦法:使用熔斷器(也叫斷路器),注意:當(dāng)這個(gè)熔斷器關(guān)閉的時(shí)候,外面的請(qǐng)求可以直接調(diào)用,如果打開,就把外界的請(qǐng)求給阻斷了。

具體的做法是:系統(tǒng)會(huì)檢測(cè)請(qǐng)求失敗的比率(失敗數(shù)/總請(qǐng)求數(shù)), 一旦這個(gè)比率達(dá)到一個(gè)閾值的時(shí)候,熔斷器就開啟, 直接拒絕執(zhí)行用戶請(qǐng)求。然后休眠一段時(shí)間,嘗試放過一部分流量(比如一個(gè)請(qǐng)求),如果調(diào)用成功,熔斷器閉合,恢復(fù)到正常狀態(tài),否則繼續(xù)進(jìn)行休眠周期。

API

現(xiàn)在有了新的線程池,對(duì)程序員來講,該如何使用呢? 原來是這么做的:

  1. UserService service = ... 獲得用戶服務(wù)... 
  2. User user = service.getUser(userID); 

現(xiàn)在,為了利用新的線程池, 需要做一層封裝:

  1. UserService service = ... 獲得用戶服務(wù)... 
  2. UserServiceCmd  cmd = new UserServiceCmd(service, userID); 
  3. User user = cmd.execute(); 

看到?jīng)]有? UserService 被封裝了一層, 放到了一個(gè)UserServiceCmd中去執(zhí)行。

這個(gè)Command代碼是這個(gè)樣子的:

  1. public class UserServiceCmd    extends HystrixCommand<User> { 
  2.   private UserService userService = null
  3.   private String userID = null
  4.   …… 
  5.  
  6.   public UserServiceCmd(UserService userService, 
  7.                         String userID) { 
  8.     …… 
  9.     this.userService = userService; 
  10.     this.userID = userID; 
  11.   } 
  12.  
  13.   @Override 
  14.   protected User run(){         
  15.     return userService.getUser(userID);         
  16.   } 
  17.  
  18.   @Override 
  19.   protected User getFallback() {         
  20.     return annonymousUser; 
  21.   } 

看起來非常簡(jiǎn)單吧, 可是背后的魔法是什么呢?

實(shí)際上,在這個(gè)UserServiceCmd執(zhí)行的時(shí)候,會(huì)使用另外一個(gè)線程池的線程去調(diào)用那個(gè)run()方法。

 

(注:這是一種同步調(diào)用,實(shí)際上還可以異步調(diào)用)

線程池的維護(hù)是在HystrixCommand這個(gè)父類中(命令模式),不需要程序員處理,程序員只需要告訴它: 我需要幾個(gè)線程,就可以了。

眼光敏銳的你也許已經(jīng)猜到,這里還采用了設(shè)計(jì)模式模板方法!

HystrixCommand它定義了一個(gè)抽象的方法: run(), 這個(gè)方法需要程序員去實(shí)現(xiàn)(例如前面的UserServiceCmd ), 父類的的execute方法會(huì)調(diào)用程序員寫的run()方法。

 

你也許還會(huì)注意到,還有一個(gè)叫做getFallback()的方法,這是干嘛用的?

其實(shí)前面的例子中我們只說道了線程池耗盡的時(shí)候,直接返回。 但是大部分情況下總得返回一點(diǎn)兒東西吧,比如UserServiceCmd,我們也許可以返回一個(gè)匿名的用戶給調(diào)用方。

這就是所謂的撤退,退卻(Fallback)邏輯。

當(dāng)然,這個(gè)邏輯也可以用在熔斷器開啟,調(diào)用失敗,超時(shí)等情況下。

一個(gè)粗略的、大致的流程圖是這樣的:

 

Netflix把這些功能(當(dāng)然,這里只是概要介紹,還有很多其他功能)給組裝起來,形成了一個(gè)開源的庫,叫做Hystrix,就是豪豬,渾身是刺,自我保護(hù),還是挺貼切的。

 

后記

剛寫完這個(gè)文章,就得到了一個(gè)”悲慘“的消息: Hystrix不再開發(fā)新功能,將進(jìn)入維護(hù)模式。 考慮到Hystrix巨大的使用量,學(xué)習(xí)它還是非常有價(jià)值的。

Netflix推薦大家轉(zhuǎn)向Resilience4j,看來又有新的玩具可以研究下了,興奮!

這是個(gè)相對(duì)新的項(xiàng)目,影響力和使用量現(xiàn)在還不能和Hystrix相比。

Resilience4j全面擁抱了Java 8和函數(shù)式編程, 他的核心功能包括:斷路器,限速,隔離(不再支持線程池),自動(dòng)重試,響應(yīng)的緩存, 看,核心的功能還是類似的, resilience4j能發(fā)展到什么程度,我們拭目以待吧。

【本文為51CTO專欄作者“劉欣”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過作者微信公眾號(hào)coderising獲取授權(quán)】

 

戳這里,看該作者更多好文

責(zé)任編輯:武曉燕 來源: 51CTO專欄
相關(guān)推薦

2020-09-26 10:56:33

服務(wù)器熔斷服務(wù)隔離

2023-11-06 08:26:11

Spring微服務(wù)架構(gòu)

2021-02-07 09:05:56

微服務(wù)結(jié)構(gòu)云原生

2023-01-29 09:06:24

微服務(wù)劃分關(guān)聯(lián)

2023-12-15 09:57:13

微服務(wù)鏈路服務(wù)

2021-07-20 08:03:43

微服務(wù)應(yīng)用程序

2022-01-17 10:55:50

微服務(wù)API網(wǎng)關(guān)

2020-07-28 08:32:57

微服務(wù)API網(wǎng)關(guān)熔斷

2022-11-02 08:31:53

BFF架構(gòu)App

2023-12-08 13:20:00

DDDSOA微服務(wù)

2021-09-06 11:34:47

架構(gòu)微服務(wù)Hystrix

2018-05-09 08:18:26

微服務(wù)改造架構(gòu)

2020-11-26 18:18:21

微服務(wù)業(yè)務(wù)規(guī)模技術(shù)

2024-04-19 08:49:50

微服務(wù)RPC事件驅(qū)動(dòng)

2022-08-04 08:46:16

單體架構(gòu)微服務(wù)事務(wù)管理

2021-06-08 07:04:45

Service Mes微服務(wù)熔斷

2023-03-01 08:57:32

2024-07-31 09:09:20

2018-05-14 08:36:53

微服務(wù)接入層動(dòng)靜資源

2024-02-21 07:24:21

微服務(wù)單體架構(gòu)MVC
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)