一玄渗、前言
看過了上一篇文章之后,我們應該掌握了 Hystrix 基本的使用方法狸眼。我們應該可以通過應用 Hystrix藤树,保護我們的應用免受延遲故障的危害。但我們只是大致配置了 HystrixCommand
拓萌,設(shè)置了相對寬松的線程池和超時時間等參數(shù)岁钓。這樣雖然可以快速應用 Hystrix,但系統(tǒng)的可用性還是可以通過配置調(diào)優(yōu)進一步的提高微王。那對 Hystrix 配置的第一步就是獲取 Hystrix 的運行數(shù)據(jù)屡限,這就用到了 Hystrix 的監(jiān)控功能。所以炕倘,本文將向大家介紹一下 Hystrix 自帶的 Dashboard 功能的使用和擴展钧大。
二、內(nèi)置的監(jiān)控:Hystrix Dashboard
如上所述罩旋,Hystrix 提供了一個 Dashboard 功能啊央,用于提供對 Hystrix 相關(guān)運行數(shù)據(jù)的監(jiān)控和展示。
▼ 正常的 HystrixCommand 的監(jiān)控圖
▼ 發(fā)生熔斷時 HystrixCommand 的監(jiān)控圖
每個 Command 的監(jiān)控圖中都有 Host 和 Cluster 兩個 TPS 數(shù)據(jù)涨醋。如果是單機的 Dashboard瓜饥,那這兩個數(shù)值是相同的,集群 Dashboard 則會有不同的顯示浴骂。
集群的 Dashboard 可以自己實現(xiàn)乓土,也可以利用 Netflix Turbine 快速搭建。原理是聚合收集 Hystrix Metrics Stream 的數(shù)據(jù)實現(xiàn)的靠闭。所以帐我,實現(xiàn)監(jiān)控的基礎(chǔ)是開啟 Hystrix Metrics Stream 功能坎炼。
監(jiān)控信息詳解
▼ 一個 HystrixCommand 完整的監(jiān)控信息
- 綠色計數(shù): 表示成功的請求數(shù)
- 藍色計數(shù): 表示斷路器打開后,直接被短路的請求數(shù)
- 黃色計數(shù): 表示請求超時數(shù)
- 紫色計數(shù): 表示因為線程池滿而被拒絕的請求數(shù)
- 紅色計數(shù): 表示因為異常而導致失敗的請求數(shù)
- 灰色百分比: 表示的是10秒內(nèi)的錯誤率統(tǒng)計
- Hosts: 應用個數(shù)
- Median: Command 的中位數(shù)時間
- Mean: Command 的平均時間
- 90th/99th/99.5th: P90拦键、P99谣光、P99.5 時間
- Rolling 10 second counters: 說明一下計數(shù)都是在一個10秒的滾動窗口內(nèi)統(tǒng)計的
- with 1 second granularity: 這個滾動窗口是以1秒為粒度進行統(tǒng)計的
所有技術(shù)和百分比的統(tǒng)計窗口都是10秒(默認值)
配置 Hystrix Metrics Stream
上一節(jié)展示的各種監(jiān)控數(shù)據(jù)均來自被監(jiān)控服務上 Hystrix Metrics Stream 的輸出,接下來介紹如何開啟 Hystrix Metrics Stream芬为。
原生方式
要開啟 Hystrix Metrics Stream萄金,我們需要做如下工作:
配置 Maven
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-metrics-event-stream</artifactId>
<version>${hystrix.version}</version>
</dependency>
配置 Servlet
<servlet>
<description></description>
<display-name>HystrixMetricsStreamServlet</display-name>
<servlet-name>HystrixMetricsStreamServlet</servlet-name>
<servlet-class>
com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HystrixMetricsStreamServlet</servlet-name>
<url-pattern>/hystrix.stream</url-pattern>
</servlet-mapping>
在配置完成之后,通過瀏覽器打開 http://server:port/hystrix.stream 就能看到如下的數(shù)據(jù):
ping:
data: {"type":"HystrixCommand","name":"AuthenticationCommand","group":"AuthenticationCommandGroup","currentTime":1503645428876,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":25,"rollingCountBadRequests":0,"rollingCountCollapsedRequests":0,"rollingCountEmit":0,"rollingCountExceptionsThrown":0,"rollingCountFailure":0,"rollingCountFallbackEmit":0,"rollingCountFallbackFailure":0,"rollingCountFallbackMissing":0,"rollingCountFallbackRejection":0,"rollingCountFallbackSuccess":0,"rollingCountResponsesFromCache":0,"rollingCountSemaphoreRejected":0,"rollingCountShortCircuited":0,"rollingCountSuccess":27,"rollingCountThreadPoolRejected":0,"rollingCountTimeout":0,"currentConcurrentExecutionCount":0,"rollingMaxConcurrentExecutionCount":1,"latencyExecute_mean":6,"latencyExecute":{"0":4,"25":5,"50":6,"75":7,"90":8,"95":9,"99":26,"99.5":26,"100":26},"latencyTotal_mean":6,"latencyTotal":{"0":4,"25":5,"50":6,"75":7,"90":8,"95":9,"99":26,"99.5":26,"100":26},"propertyValue_circuitBreakerRequestVolumeThreshold":20,"propertyValue_circuitBreakerSleepWindowInMilliseconds":5000,"propertyValue_circuitBreakerErrorThresholdPercentage":20,"propertyValue_circuitBreakerForceOpen":false,"propertyValue_circuitBreakerForceClosed":false,"propertyValue_circuitBreakerEnabled":true,"propertyValue_executionIsolationStrategy":"THREAD","propertyValue_executionIsolationThreadTimeoutInMilliseconds":200,"propertyValue_executionTimeoutInMilliseconds":200,"propertyValue_executionIsolationThreadInterruptOnTimeout":true,"propertyValue_executionIsolationThreadPoolKeyOverride":null,"propertyValue_executionIsolationSemaphoreMaxConcurrentRequests":10,"propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests":10,"propertyValue_metricsRollingStatisticalWindowInMilliseconds":10000,"propertyValue_requestCacheEnabled":false,"propertyValue_requestLogEnabled":false,"reportingHosts":1,"threadPool":"PassportCommandThreadPool"}
這些就是 Hystrix 相關(guān)的監(jiān)控數(shù)據(jù)流媚朦,包括了接口響應時間氧敢、TPS、熔斷等相關(guān)的數(shù)據(jù)询张。
Spring Boot
如果使用了 Spring Boot孙乖,我們啟用 Stream 的方法略有不同,但同樣簡單:
配置 Maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
配置 Spring Boot
@EnableHystrix
@SpringBootApplication
public class HystrixWorkshopApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixWorkshopApplication.class, args);
}
}
運行 Hystrix Dashboard 服務
但是份氧,我們肯定不能直接通過這樣的方式監(jiān)控 Hystrix唯袄。所以,Hystrix 提供了一個 Dashboard 應用蜗帜。Dashboard 是一個單獨的應用恋拷,我們可以獨立部署,另外 Spring Cloud 也提供了一個注解厅缺,開啟 Dashboard 功能蔬顾。Dashboard 的基本的安裝配置功能不在這里描述了。
▼ Hystrix Dashboard 的界面如下圖所示
在第一個文本框填入 Hystrix Stream 的地址即可看到本文開頭的界面湘捎。
如果需要監(jiān)控整個 Hystrix 集群诀豁,就需要使用 Turbine 應用。Turbine 也是 Netflix 開源的一個服務消痛。
Hystrix Metrics 的優(yōu)缺點
優(yōu)點:
統(tǒng)計粒度星胰:時間粒度和監(jiān)控單元粒度都哭≈壬。可以幫助我們發(fā)現(xiàn)粗粒度監(jiān)控時不容易發(fā)現(xiàn)的問題。
缺點:
數(shù)據(jù)沒有持久化欺矫,無法查看歷史數(shù)據(jù)
三纱新、與自有監(jiān)控和報警系統(tǒng)的集成
監(jiān)控
對于多數(shù)公司來說,使用 Hystrix Stream 和 Turbine 存在一個明顯的不足穆趴,那就是無法查看歷史的監(jiān)控數(shù)據(jù)脸爱。
這個功能還是很重要的,因為在使用 Hystrix未妹,剛開始簿废,超時時間空入、線程池等參數(shù)配置的都比較隨意。后續(xù)我們需要進行配置調(diào)整族檬,依據(jù)就來自 Hystrix Dashboard 上的數(shù)據(jù)歪赢。但如果無法看到歷史的數(shù)據(jù),那就很不方便了单料。
目前埋凯,Hystrix 并沒有提供任何機制用于將運行數(shù)據(jù)上傳至第三方監(jiān)控系統(tǒng)的機制,但我們可以參考 HystrixMetricsStreamServlet
的實現(xiàn)方式扫尖。
HystrixMetricsStreamServlet
是通過輪詢 HystrixCommandMetrics
白对、HystrixThreadPoolMetrics
和 HystrixCollapserMetrics
中的數(shù)據(jù)實現(xiàn)監(jiān)控的。因此换怖,我們也可以采用類似的方式甩恼,輪詢這三個類中的數(shù)據(jù),然后將這些數(shù)據(jù)上傳到第三方監(jiān)控系統(tǒng)沉颂。上傳之后媳拴,在通過相應監(jiān)控系統(tǒng)的持久化功能,從而實現(xiàn)對監(jiān)控數(shù)據(jù)的保存兆览。
private HystrixDashboardStream(int delayInMs) {
this.delayInMs = delayInMs;
this.singleSource = Observable.interval(delayInMs, TimeUnit.MILLISECONDS)
.map(new Func1<Long, DashboardData>() {
@Override
public DashboardData call(Long timestamp) {
return new DashboardData(
HystrixCommandMetrics.getInstances(),
HystrixThreadPoolMetrics.getInstances(),
HystrixCollapserMetrics.getInstances()
);
}
})
.doOnSubscribe(new Action0() {
@Override
public void call() {
isSourceCurrentlySubscribed.set(true);
}
})
.doOnUnsubscribe(new Action0() {
@Override
public void call() {
isSourceCurrentlySubscribed.set(false);
}
})
.share()
.onBackpressureDrop();
}
報警
注:這一段內(nèi)容和 Hystrix 本身的使用沒有直接關(guān)系屈溉,而是和 Hystrix 相關(guān)的微服務治理相關(guān)的內(nèi)容。但建議負責技術(shù)抬探、架構(gòu)子巾,以及負責基礎(chǔ)組件和服務研發(fā)的同學閱讀
在有了監(jiān)控數(shù)據(jù)之后,報警功能也是水到渠成小压,所以這里不談如何實現(xiàn)基于 Hystrix 監(jiān)控數(shù)據(jù)的報警功能线梗。這里我們討論一下我們是否需要基于 Hystrix 監(jiān)控數(shù)據(jù)的報警功能?如果需要怠益,都需要針對哪些指標添加報警仪搔?
之所以討論這個問題,是因為有很多全鏈路監(jiān)控解決方案蜻牢,例如 Spring Cloud Sleuth烤咧、Pinpoint 等,都支持對 Hystrix 的監(jiān)控抢呆。所以煮嫌,監(jiān)控報警功能并不依賴于 Hystrix 自帶的監(jiān)控數(shù)據(jù)輸出。所以抱虐,如果只需要基本的監(jiān)控報警功能昌阿,完全是不需要 Hystrix Metrics 和 Dashboard 功能的。
但 Hystrix 相關(guān)的監(jiān)控數(shù)據(jù)不同于其它技術(shù),除了超時和錯誤的監(jiān)控懦冰,還有其它很多細粒度的監(jiān)控數(shù)據(jù)灶轰。例如,熔斷次數(shù)刷钢、線程池拒絕次數(shù)等等框往。
對于這些細粒度的監(jiān)控數(shù)據(jù),我認為不應該將它們同超時和錯誤監(jiān)控等同看待闯捎。前者更多的是用于配置調(diào)優(yōu)椰弊,后者則主要是一種常規(guī)的監(jiān)控方式。如果我們將 Hystrix Metrics 所提供的所有數(shù)據(jù)都納入監(jiān)控瓤鼻,不僅監(jiān)控系統(tǒng)秉版,而且,更重要的是茬祷,技術(shù)人員可能會不堪重sao負rao清焕。過多的監(jiān)控有時會起到相反的作用,即讓技術(shù)人員忽視監(jiān)控祭犯。
我認為 Hystrix 相關(guān)的報警的一個原則是秸妥,報警還應該局限于主要的指標(請求時間、異常)沃粗。對于 Hystrix 特有的粥惧、細粒度的運行數(shù)據(jù),我們需要做到有據(jù)可查最盅。以方便開發(fā)人員調(diào)優(yōu)