成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

防雪崩利器:熔斷器 Hystrix 的原理與使用

JessYanCoding / 3195人閱讀

摘要:前言分布式系統(tǒng)中經(jīng)常會出現(xiàn)某個基礎(chǔ)服務(wù)不可用造成整個系統(tǒng)不可用的情況這種現(xiàn)象被稱為服務(wù)雪崩效應(yīng)為了應(yīng)對服務(wù)雪崩一種常見的做法是手動服務(wù)降級而的出現(xiàn)給我們提供了另一種選擇服務(wù)雪崩效應(yīng)的定義服務(wù)雪崩效應(yīng)是一種因服務(wù)提供者的不可用導(dǎo)致服務(wù)調(diào)用者的

前言

分布式系統(tǒng)中經(jīng)常會出現(xiàn)某個基礎(chǔ)服務(wù)不可用造成整個系統(tǒng)不可用的情況, 這種現(xiàn)象被稱為服務(wù)雪崩效應(yīng). 為了應(yīng)對服務(wù)雪崩, 一種常見的做法是手動服務(wù)降級. 而Hystrix的出現(xiàn),給我們提供了另一種選擇.

服務(wù)雪崩效應(yīng)的定義

服務(wù)雪崩效應(yīng)是一種因 服務(wù)提供者 的不可用導(dǎo)致 服務(wù)調(diào)用者 的不可用,并將不可用 逐漸放大 的過程.如果所示:

上圖中, A為服務(wù)提供者, B為A的服務(wù)調(diào)用者, C和D是B的服務(wù)調(diào)用者. 當A的不可用,引起B(yǎng)的不可用,并將不可用逐漸放大C和D時, 服務(wù)雪崩就形成了.

服務(wù)雪崩效應(yīng)形成的原因

我把服務(wù)雪崩的參與者簡化為 服務(wù)提供者服務(wù)調(diào)用者, 并將服務(wù)雪崩產(chǎn)生的過程分為以下三個階段來分析形成的原因:

服務(wù)提供者不可用

重試加大流量

服務(wù)調(diào)用者不可用

服務(wù)雪崩的每個階段都可能由不同的原因造成, 比如造成 服務(wù)不可用 的原因有:

硬件故障

程序Bug

緩存擊穿

用戶大量請求

硬件故障可能為硬件損壞造成的服務(wù)器主機宕機, 網(wǎng)絡(luò)硬件故障造成的服務(wù)提供者的不可訪問.
緩存擊穿一般發(fā)生在緩存應(yīng)用重啟, 所有緩存被清空時,以及短時間內(nèi)大量緩存失效時. 大量的緩存不命中, 使請求直擊后端,造成服務(wù)提供者超負荷運行,引起服務(wù)不可用.
在秒殺和大促開始前,如果準備不充分,用戶發(fā)起大量請求也會造成服務(wù)提供者的不可用.

而形成 重試加大流量 的原因有:

用戶重試

代碼邏輯重試

在服務(wù)提供者不可用后, 用戶由于忍受不了界面上長時間的等待,而不斷刷新頁面甚至提交表單.
服務(wù)調(diào)用端的會存在大量服務(wù)異常后的重試邏輯.
這些重試都會進一步加大請求流量.

最后, 服務(wù)調(diào)用者不可用 產(chǎn)生的主要原因是:

同步等待造成的資源耗盡

當服務(wù)調(diào)用者使用 同步調(diào)用 時, 會產(chǎn)生大量的等待線程占用系統(tǒng)資源. 一旦線程資源被耗盡,服務(wù)調(diào)用者提供的服務(wù)也將處于不可用狀態(tài), 于是服務(wù)雪崩效應(yīng)產(chǎn)生了.

服務(wù)雪崩的應(yīng)對策略

針對造成服務(wù)雪崩的不同原因, 可以使用不同的應(yīng)對策略:

流量控制

改進緩存模式

服務(wù)自動擴容

服務(wù)調(diào)用者降級服務(wù)

流量控制 的具體措施包括:

網(wǎng)關(guān)限流

用戶交互限流

關(guān)閉重試

因為Nginx的高性能, 目前一線互聯(lián)網(wǎng)公司大量采用Nginx+Lua的網(wǎng)關(guān)進行流量控制, 由此而來的OpenResty也越來越熱門.

用戶交互限流的具體措施有: 1. 采用加載動畫,提高用戶的忍耐等待時間. 2. 提交按鈕添加強制等待時間機制.

改進緩存模式 的措施包括:

緩存預(yù)加載

同步改為異步刷新

服務(wù)自動擴容 的措施主要有:

AWS的auto scaling

服務(wù)調(diào)用者降級服務(wù) 的措施包括:

資源隔離

對依賴服務(wù)進行分類

不可用服務(wù)的調(diào)用快速失敗

資源隔離主要是對調(diào)用服務(wù)的線程池進行隔離.

我們根據(jù)具體業(yè)務(wù),將依賴服務(wù)分為: 強依賴和若依賴. 強依賴服務(wù)不可用會導(dǎo)致當前業(yè)務(wù)中止,而弱依賴服務(wù)的不可用不會導(dǎo)致當前業(yè)務(wù)的中止.

不可用服務(wù)的調(diào)用快速失敗一般通過 超時機制, 熔斷器 和熔斷后的 降級方法 來實現(xiàn).

使用Hystrix預(yù)防服務(wù)雪崩

Hystrix [h?st"r?ks]的中文含義是豪豬, 因其背上長滿了刺,而擁有自我保護能力. Netflix的 Hystrix 是一個幫助解決分布式系統(tǒng)交互時超時處理和容錯的類庫, 它同樣擁有保護系統(tǒng)的能力.

Hystrix的設(shè)計原則包括:

資源隔離

熔斷器

命令模式

資源隔離

貨船為了進行防止漏水和火災(zāi)的擴散,會將貨倉分隔為多個, 如下圖所示:

這種資源隔離減少風(fēng)險的方式被稱為:Bulkheads(艙壁隔離模式).
Hystrix將同樣的模式運用到了服務(wù)調(diào)用者上.

在一個高度服務(wù)化的系統(tǒng)中,我們實現(xiàn)的一個業(yè)務(wù)邏輯通常會依賴多個服務(wù),比如:
商品詳情展示服務(wù)會依賴商品服務(wù), 價格服務(wù), 商品評論服務(wù). 如圖所示:

調(diào)用三個依賴服務(wù)會共享商品詳情服務(wù)的線程池. 如果其中的商品評論服務(wù)不可用, 就會出現(xiàn)線程池里所有線程都因等待響應(yīng)而被阻塞, 從而造成服務(wù)雪崩. 如圖所示:

Hystrix通過將每個依賴服務(wù)分配獨立的線程池進行資源隔離, 從而避免服務(wù)雪崩.
如下圖所示, 當商品評論服務(wù)不可用時, 即使商品服務(wù)獨立分配的20個線程全部處于同步等待狀態(tài),也不會影響其他依賴服務(wù)的調(diào)用.

熔斷器模式

熔斷器模式定義了熔斷器開關(guān)相互轉(zhuǎn)換的邏輯:

服務(wù)的健康狀況 = 請求失敗數(shù) / 請求總數(shù).
熔斷器開關(guān)由關(guān)閉到打開的狀態(tài)轉(zhuǎn)換是通過當前服務(wù)健康狀況和設(shè)定閾值比較決定的.

當熔斷器開關(guān)關(guān)閉時, 請求被允許通過熔斷器. 如果當前健康狀況高于設(shè)定閾值, 開關(guān)繼續(xù)保持關(guān)閉. 如果當前健康狀況低于設(shè)定閾值, 開關(guān)則切換為打開狀態(tài).

當熔斷器開關(guān)打開時, 請求被禁止通過.

當熔斷器開關(guān)處于打開狀態(tài), 經(jīng)過一段時間后, 熔斷器會自動進入半開狀態(tài), 這時熔斷器只允許一個請求通過. 當該請求調(diào)用成功時, 熔斷器恢復(fù)到關(guān)閉狀態(tài). 若該請求失敗, 熔斷器繼續(xù)保持打開狀態(tài), 接下來的請求被禁止通過.

熔斷器的開關(guān)能保證服務(wù)調(diào)用者在調(diào)用異常服務(wù)時, 快速返回結(jié)果, 避免大量的同步等待. 并且熔斷器能在一段時間后繼續(xù)偵測請求執(zhí)行結(jié)果, 提供恢復(fù)服務(wù)調(diào)用的可能.

命令模式

Hystrix使用命令模式(繼承HystrixCommand類)來包裹具體的服務(wù)調(diào)用邏輯(run方法), 并在命令模式中添加了服務(wù)調(diào)用失敗后的降級邏輯(getFallback).
同時我們在Command的構(gòu)造方法中可以定義當前服務(wù)線程池和熔斷器的相關(guān)參數(shù). 如下代碼所示:

public class Service1HystrixCommand extends HystrixCommand {
  private Service1 service;
  private Request request;

  public Service1HystrixCommand(Service1 service, Request request){
    supper(
      Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ServiceGroup"))
          .andCommandKey(HystrixCommandKey.Factory.asKey("servcie1query"))
          .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("service1ThreadPool"))
          .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
            .withCoreSize(20))//服務(wù)線程池數(shù)量
          .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
            .withCircuitBreakerErrorThresholdPercentage(60)//熔斷器關(guān)閉到打開閾值
            .withCircuitBreakerSleepWindowInMilliseconds(3000)//熔斷器打開到關(guān)閉的時間窗長度
      ))
      this.service = service;
      this.request = request;
    );
  }

  @Override
  protected Response run(){
    return service1.call(request);
  }

  @Override
  protected Response getFallback(){
    return Response.dummy();
  }
}

在使用了Command模式構(gòu)建了服務(wù)對象之后, 服務(wù)便擁有了熔斷器和線程池的功能.

Hystrix的內(nèi)部處理邏輯

下圖為Hystrix服務(wù)調(diào)用的內(nèi)部邏輯:

構(gòu)建Hystrix的Command對象, 調(diào)用執(zhí)行方法.

Hystrix檢查當前服務(wù)的熔斷器開關(guān)是否開啟, 若開啟, 則執(zhí)行降級服務(wù)getFallback方法.

若熔斷器開關(guān)關(guān)閉, 則Hystrix檢查當前服務(wù)的線程池是否能接收新的請求, 若超過線程池已滿, 則執(zhí)行降級服務(wù)getFallback方法.

若線程池接受請求, 則Hystrix開始執(zhí)行服務(wù)調(diào)用具體邏輯run方法.

若服務(wù)執(zhí)行失敗, 則執(zhí)行降級服務(wù)getFallback方法, 并將執(zhí)行結(jié)果上報Metrics更新服務(wù)健康狀況.

若服務(wù)執(zhí)行超時, 則執(zhí)行降級服務(wù)getFallback方法, 并將執(zhí)行結(jié)果上報Metrics更新服務(wù)健康狀況.

若服務(wù)執(zhí)行成功, 返回正常結(jié)果.

若服務(wù)降級方法getFallback執(zhí)行成功, 則返回降級結(jié)果.

若服務(wù)降級方法getFallback執(zhí)行失敗, 則拋出異常.

Hystrix Metrics的實現(xiàn)

Hystrix的Metrics中保存了當前服務(wù)的健康狀況, 包括服務(wù)調(diào)用總次數(shù)和服務(wù)調(diào)用失敗次數(shù)等. 根據(jù)Metrics的計數(shù), 熔斷器從而能計算出當前服務(wù)的調(diào)用失敗率, 用來和設(shè)定的閾值比較從而決定熔斷器的狀態(tài)切換邏輯. 因此Metrics的實現(xiàn)非常重要.

1.4之前的滑動窗口實現(xiàn)

Hystrix在這些版本中的使用自己定義的滑動窗口數(shù)據(jù)結(jié)構(gòu)來記錄當前時間窗的各種事件(成功,失敗,超時,線程池拒絕等)的計數(shù).
事件產(chǎn)生時, 數(shù)據(jù)結(jié)構(gòu)根據(jù)當前時間確定使用舊桶還是創(chuàng)建新桶來計數(shù), 并在桶中對計數(shù)器經(jīng)行修改.
這些修改是多線程并發(fā)執(zhí)行的, 代碼中有不少加鎖操作,邏輯較為復(fù)雜.

1.5之后的滑動窗口實現(xiàn)

Hystrix在這些版本中開始使用RxJava的Observable.window()實現(xiàn)滑動窗口.
RxJava的window使用后臺線程創(chuàng)建新桶, 避免了并發(fā)創(chuàng)建桶的問題.
同時RxJava的單線程無鎖特性也保證了計數(shù)變更時的線程安全. 從而使代碼更加簡潔.
以下為我使用RxJava的window方法實現(xiàn)的一個簡易滑動窗口Metrics, 短短幾行代碼便能完成統(tǒng)計功能,足以證明RxJava的強大:

@Test
public void timeWindowTest() throws Exception{
  Observable source = Observable.interval(50, TimeUnit.MILLISECONDS).map(i -> RandomUtils.nextInt(2));
  source.window(1, TimeUnit.SECONDS).subscribe(window -> {
    int[] metrics = new int[2];
    window.subscribe(i -> metrics[i]++,
      InternalObservableUtils.ERROR_NOT_IMPLEMENTED,
      () -> System.out.println("窗口Metrics:" + JSON.toJSONString(metrics)));
  });
  TimeUnit.SECONDS.sleep(3);
}
總結(jié)

通過使用Hystrix,我們能方便的防止雪崩效應(yīng), 同時使系統(tǒng)具有自動降級和自動恢復(fù)服務(wù)的效果.

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/66218.html

相關(guān)文章

  • 雪崩利器斷器 Hystrix 原理使用

    摘要:前言分布式系統(tǒng)中經(jīng)常會出現(xiàn)某個基礎(chǔ)服務(wù)不可用造成整個系統(tǒng)不可用的情況這種現(xiàn)象被稱為服務(wù)雪崩效應(yīng)為了應(yīng)對服務(wù)雪崩一種常見的做法是手動服務(wù)降級而的出現(xiàn)給我們提供了另一種選擇服務(wù)雪崩效應(yīng)的定義服務(wù)雪崩效應(yīng)是一種因服務(wù)提供者的不可用導(dǎo)致服務(wù)調(diào)用者的 前言 分布式系統(tǒng)中經(jīng)常會出現(xiàn)某個基礎(chǔ)服務(wù)不可用造成整個系統(tǒng)不可用的情況, 這種現(xiàn)象被稱為服務(wù)雪崩效應(yīng). 為了應(yīng)對服務(wù)雪崩, 一種常見的做法是手動服...

    jayzou 評論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.39 - 什么!服務(wù)器炸了?

    摘要:有一次別人的云服務(wù)器被攻擊,提供商竟然重啟了物理機然后又諸多悲劇出現(xiàn)。造成微博服務(wù)短暫不可用。通過建立工具來診斷問題,并創(chuàng)建一種復(fù)盤事故的文化來推動并作出改進,防止未來發(fā)生故障。 showImg(https://segmentfault.com/img/bV0jif?w=900&h=385); 相信小伙伴們在上網(wǎng)或者玩游戲的時候一定都遇到過無法訪問的情況。服務(wù)器炸了的原因有各種各樣,下...

    1treeS 評論0 收藏0
  • Hystrix 停止開發(fā)。。。Spring Cloud 何去何從?

    摘要:棧長得到消息,停止開發(fā)了。。。是一個輕量級的容錯組件,其靈感來自于,主要為和函數(shù)式編程設(shè)計的看到這里,棧長表示學(xué)不動了。。。上面說了,官方推薦替代的開源組件,這個棧長也沒有用過,查了下,資料也比較稀少。 showImg(https://segmentfault.com/img/remote/1460000017201104?w=1600&h=1066); 棧長得到消息,Hystrix ...

    陸斌 評論0 收藏0
  • SpringCloud學(xué)習(xí)(3)

    摘要:服務(wù)雪崩效應(yīng)是一種因服務(wù)提供者的不可用導(dǎo)致服務(wù)消費者的不可用并將不可用逐漸放大的過程。這種代理能夠記錄最近調(diào)用發(fā)生錯誤的次數(shù),然后決定使用允許操作繼續(xù),或者立即返回錯誤。這個自己持有的上下文默認實現(xiàn)類也是。 ?????本篇集成Hystrix,繼續(xù)搭建demo。 雪崩效應(yīng):在微服務(wù)架構(gòu)中通常會有多個服務(wù)層調(diào)用,基礎(chǔ)服務(wù)的故障可能會導(dǎo)致級聯(lián)故障,進而造成整個系統(tǒng)不可用的情況,這種現(xiàn)象被稱為...

    monw3c 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<