生活随笔
收集整理的這篇文章主要介紹了
使用Hystrix守护应用(3)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
2019獨角獸企業重金招聘Python工程師標準>>>
使用Hystrix守護應用(3) 博客分類: 架構 spring 微服務
監控HystrixCommand?
除了隔離依賴服務的調用外,Hystrix還提供了近乎實時的監控,Hystrix會實時的,累加的記錄所有關于HystrixCommand的執行信息,包括執行了每秒執行了多少請求,多少成功,多少失敗等等,更多指標請查看:https://github.com/Netflix/Hystrix/wiki/Metrics-and-Monitoring?
導出監控數據?
有了這些指標,Netflix還提供了一個類庫(hystrix-metrics-event-stream:https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-metrics-event-stream)把這些指標信息以‘text/event-stream’的格式開放給外部使用,用法非常簡單,首先,把hystrix-metrics-event-stream庫添加到項目中:?
Gradle代碼??
dependencies?{??????compile(???????????????...??????????????'com.netflix.hystrix:hystrix-metrics-event-stream:1.3.9',??????????????...??????)??}??
然后,在web.xml中配置一個Servlet來獲取Hystrix提供的數據:?
Xml代碼??
<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://hostname:port/appname/hystrix.stream, 可以看到如下的輸出:?
data: {"type":"HystrixCommand","name":"Address","group":"Address","currentTime":1393154954462,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":0,"rollingCountCollapsedRequests"......
系統會不斷刷新以獲取實時的數據。?
Dashboard?
從上面的輸出可以看到,這樣的純字符輸出可讀性實在太差,運維人員很難從中就看出系統的當前狀態,于是Netflix又開發了一個開源項目(Dashboard:https://github.com/Netflix/Hystrix/wiki/Dashboard)來可視化這些數據,幫助運維人員更直觀的了解系統的當前狀態,Dashboard使用起來非常方便,其就是一個Web項目,你只需要把war包(http://search.maven.org/#browse%7C1045347652)下載下來,放到一個Web容器(Tomcat,Jetty等)中即可。?
啟動WebContainer訪問Dashboard主頁,可以看到如下的界面:?
填入上面獲取hystrix.stream的URL,點擊Monitor,即可看到實時的監控畫面:?
Dashboard主要展示了2類信息,一是HystrixCommand的執行情況,Hystrix Wiki上詳細說明了圖上的每個指標代表的含義:?
?
二是線程池的狀態,包括線程池名,大小,當前活躍線程說,最大活躍線程數,排隊隊列大小等。?
Turbine?
在復雜的分布式系統中,相同服務的結點經常需要部署上百甚至上千個,很多時候,運維人員希望能夠把相同服務的節點狀態以一個整體集群的形式展現出來,這樣可以更好的把握整個系統的狀態。 為此,Netflix又提供了一個開源項目(Turbine)來提供把多個hystrix.stream的內容聚合為一個數據源供Dashboard展示。?
Turbine有2種用法,其一是內嵌Turbine到你的項目中;另外一個是把Turbine當做一個獨立的Module。不管哪種用法,配置文件都是一致的。 Turbine默認會在classpath下查找配置文件:config.properties, 該文件中會配置:
1. Turbine在監控哪些集群:turbine.aggregator.clusterConfig=cluster-1,cluster-2?
2. Turbine怎樣獲取到節點的監控信息(hystrix.stream):turbine.instanceUrlSuffix.<cluster-name> = :/HystrixDemo/hystrix.stream?
3. 集群下有哪些節點:turbine.ConfigPropertyBasedDiscovery.cluster-1.instances=localhost:8080,localhost:8081?
上面這些都是最簡單的配置方法 Turbine使用了Netflix的另一個開源項目Archaius(https://github.com/Netflix/archaius)來做配置文件的管理,其提供了非常強大的配置文件管理策略,有需要的同學可以深入研究(https://github.com/Netflix/Turbine/wiki/Configuration)。?
使用Turbine的步驟一般如下:?
1. 下載Turbine.war(https://github.com/downloads/Netflix/Turbine/turbine-web-1.0.0.war),并把其置于Web容器中。?
2. 在Turbine項目的WEB-INF/classes目錄下創建配置文件config.properties:?
3. 啟動Turbine服務?
4. 在Dashboard項目中填入Tubine項目提供的stream: http://hostname:port/turbine/turbine.stream也可添加?cluster=<cluster-name>參數只監控某一個Cluster. Dashboard上展示的指標和之前是一樣的,只是數據是已經聚合的數據了。?
為遺留系統添加Hystrix?
最后,來看看如何在不改動已有代碼的前提下為應用添加Hystrix支持,在Spring的世界,以不改變已有代碼的前提添加功能的最好解決方案就是aop,還是使用上面的示例,假設已有一個Customer Service, Customer Service會調用ContactDao和AddressDao去獲取Contact和Address信息。 如下:?
Java代碼??
public?Customer?getCustomerThroughDao(String?customerId)?{??????????logger.info("Get?Customer?{}",?customerId);??????????try?{??????????????Customer?customer?=?new?Customer(customerId,?"xianlinbox");??????????????customer.setContact(contactDao.getContact(customerId));??????????????customer.setAddress(addressDao.getAddress(customerId));??????????????return?customer;??????????}?catch?(Exception?e)?{??????????????e.printStackTrace();??????????}??????????return?null;??????}????public?class?AddressDao?{??????private?Logger?logger?=?LoggerFactory.getLogger(AddressDao.class);????????public?Address?getAddress(String?customerId)?throws?IOException?{??????????logger.info("Get?address?for?customer?{}",?customerId);??????????String?response?=?Request.Get("http://localhost:9090/customer/"?+?customerId?+?"/address")??????????????????.connectTimeout(1000)??????????????????.socketTimeout(1000)??????????????????.execute()??????????????????.returnContent()??????????????????.asString();????????????return?new?ObjectMapper().readValue(response,?Address.class);??????}??}????public?class?ContactDao?{??????private?Logger?logger?=?LoggerFactory.getLogger(ContactDao.class);????????public?Contact?getContact(String?customerId)?throws?IOException?{??????????logger.info("Get?contact?for?customer?{}",?customerId);??????????String?response?=?Request.Get("http://localhost:9090/customer/"?+?customerId?+?"/contact")??????????????????.connectTimeout(1000)??????????????????.socketTimeout(1000)??????????????????.execute()??????????????????.returnContent()??????????????????.asString();????????????return?new?ObjectMapper().readValue(response,?Contact.class);??????}??}??
下面就來看看如何在不改動已有代碼的基礎上把ContactDao和AddressDao封裝到HystixCommand中,首先創建HystrixComnandAdvice,該類會為創建一個HystrixCommand, 然后把切面封裝到該HystrixCommand中:?
Java代碼??
public?class?HystrixCommandAdvice?{??????private?String?groupName;??????private?String?commandName;????????public?Object?runCommand(final?ProceedingJoinPoint?pjp)?{??????????return?wrapWithHystrixCommnad(pjp).execute();??????}????????private?HystrixCommand<Object>?wrapWithHystrixCommnad(final?ProceedingJoinPoint?pjp)?{??????????return?new?HystrixCommand<Object>(setter())?{??????????????@Override ??????????????protected?Object?run()?throws?Exception?{??????????????????try?{??????????????????????return?pjp.proceed();??????????????????}?catch?(Throwable?throwable)?{??????????????????????throw?(Exception)?throwable;??????????????????}??????????????}????????????????@Override ??????????????protected?Object?getFallback()?{??????????????????return?null;??????????????}??????????};??????}????????private?HystrixCommand.Setter?setter()?{??????????return?HystrixCommand.Setter??????????????????.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupName))??????????????????.andCommandKey(HystrixCommandKey.Factory.asKey(commandName));??????}????????public?void?setGroupName(String?groupName)?{??????????this.groupName?=?groupName;??????}????????public?void?setCommandName(String?commandName)?{??????????this.commandName?=?commandName;??????}??}??
然后,只需要再為ContactDao和AddressDao配置上該類示例就行了:?
??
Xml代碼??
<bean?id="contactDaoCommand"?class="com.xianlinbox.hystrix.dao.HystrixCommandAdvice">?????????<property?name="groupName"?value="Contact"/>?????????<property?name="commandName"?value="Contact"/>?????</bean>?????<bean?id="addressDaoCommand"?class="com.xianlinbox.hystrix.dao.HystrixCommandAdvice">?????????<property?name="groupName"?value="Address"/>?????????<property?name="commandName"?value="Address"/>?????</bean>?????<aop:config>?????????<aop:aspect?id="contactServiceAspect"?ref="contactDaoCommand">?????????????<aop:pointcut?id="contactServiceTarget"???????????????????????????expression="execution(*?com.xianlinbox.hystrix.dao.ContactDao.getContact(..))"/>?????????????<aop:around?method="runCommand"?pointcut-ref="contactServiceTarget"/>?????????</aop:aspect>?????</aop:config>???????<aop:config>?????????<aop:aspect?id="addressServiceAspect"?ref="addressDaoCommand">?????????????<aop:pointcut?id="addressServiceTarget"???????????????????????????expression="execution(*?com.xianlinbox.hystrix.dao.AddressDao.getAddress(..))"/>?????????????<aop:around?method="runCommand"?pointcut-ref="addressServiceTarget"/>?????????</aop:aspect>?????</aop:config>??
該示例的系統行為和前面直接使用HystrixCommand構建的時完全一樣的。?
總結?
從全文涉及的內容中,不難看出Netflix構建了一個完整的Hystrix生態系統,這個生態系統讓Hystrix非常易于上手,同時又有非常多的配置選項和高級用法來滿足不同系統的個性化需求。對于這樣的工具,相信每個開發者都會喜歡。另外,對于Netflix這樣把自己的經驗變成工具造福整個社區的行為,不由得不贊賞。?
?
http://ningandjiao.iteye.com/blog/2171849
轉載于:https://my.oschina.net/xiaominmin/blog/1599122
總結
以上是生活随笔為你收集整理的使用Hystrix守护应用(3)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。