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代码  
  1. dependencies {
  2. compile(
  3. ...
  4. 'com.netflix.hystrix:hystrix-metrics-event-stream:1.3.9',
  5. ...
  6. )
  7. }

然后,在web.xml中配置一个Servlet来获取Hystrix提供的数据:

Xml代码  
  1. <servlet>
  2. <description></description>
  3. <display-name>HystrixMetricsStreamServlet</display-name>
  4. <servlet-name>HystrixMetricsStreamServlet</servlet-name>
  5. <servlet-class>com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet</servlet-class>
  6. </servlet>
  7. <servlet-mapping>
  8. <servlet-name>HystrixMetricsStreamServlet</servlet-name>
  9. <url-pattern>/hystrix.stream</url-pattern>
  10. </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代码  
  1. public Customer getCustomerThroughDao(String customerId) {
  2. logger.info("Get Customer {}", customerId);
  3. try {
  4. Customer customer = new Customer(customerId, "xianlinbox");
  5. customer.setContact(contactDao.getContact(customerId));
  6. customer.setAddress(addressDao.getAddress(customerId));
  7. return customer;
  8. } catch (Exception e) {
  9. e.printStackTrace();
  10. }
  11. return null;
  12. }
  13. public class AddressDao {
  14. private Logger logger = LoggerFactory.getLogger(AddressDao.class);
  15. public Address getAddress(String customerId) throws IOException {
  16. logger.info("Get address for customer {}", customerId);
  17. String response = Request.Get("http://localhost:9090/customer/" + customerId + "/address")
  18. .connectTimeout(1000)
  19. .socketTimeout(1000)
  20. .execute()
  21. .returnContent()
  22. .asString();
  23. return new ObjectMapper().readValue(response, Address.class);
  24. }
  25. }
  26. public class ContactDao {
  27. private Logger logger = LoggerFactory.getLogger(ContactDao.class);
  28. public Contact getContact(String customerId) throws IOException {
  29. logger.info("Get contact for customer {}", customerId);
  30. String response = Request.Get("http://localhost:9090/customer/" + customerId + "/contact")
  31. .connectTimeout(1000)
  32. .socketTimeout(1000)
  33. .execute()
  34. .returnContent()
  35. .asString();
  36. return new ObjectMapper().readValue(response, Contact.class);
  37. }
  38. }

下面就来看看如何在不改动已有代码的基础上把ContactDao和AddressDao封装到HystixCommand中,首先创建HystrixComnandAdvice,该类会为创建一个HystrixCommand, 然后把切面封装到该HystrixCommand中:

Java代码  
  1. public class HystrixCommandAdvice {
  2. private String groupName;
  3. private String commandName;
  4. public Object runCommand(final ProceedingJoinPoint pjp) {
  5. return wrapWithHystrixCommnad(pjp).execute();
  6. }
  7. private HystrixCommand<Object> wrapWithHystrixCommnad(final ProceedingJoinPoint pjp) {
  8. return new HystrixCommand<Object>(setter()) {
  9. @Override
  10. protected Object run() throws Exception {
  11. try {
  12. return pjp.proceed();
  13. } catch (Throwable throwable) {
  14. throw (Exception) throwable;
  15. }
  16. }
  17. @Override
  18. protected Object getFallback() {
  19. return null;
  20. }
  21. };
  22. }
  23. private HystrixCommand.Setter setter() {
  24. return HystrixCommand.Setter
  25. .withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupName))
  26. .andCommandKey(HystrixCommandKey.Factory.asKey(commandName));
  27. }
  28. public void setGroupName(String groupName) {
  29. this.groupName = groupName;
  30. }
  31. public void setCommandName(String commandName) {
  32. this.commandName = commandName;
  33. }
  34. }

然后,只需要再为ContactDao和AddressDao配置上该类示例就行了:

Xml代码  
  1. <bean id="contactDaoCommand" class="com.xianlinbox.hystrix.dao.HystrixCommandAdvice">
  2. <property name="groupName" value="Contact"/>
  3. <property name="commandName" value="Contact"/>
  4. </bean>
  5. <bean id="addressDaoCommand" class="com.xianlinbox.hystrix.dao.HystrixCommandAdvice">
  6. <property name="groupName" value="Address"/>
  7. <property name="commandName" value="Address"/>
  8. </bean>
  9. <aop:config>
  10. <aop:aspect id="contactServiceAspect" ref="contactDaoCommand">
  11. <aop:pointcut id="contactServiceTarget"
  12. expression="execution(* com.xianlinbox.hystrix.dao.ContactDao.getContact(..))"/>
  13. <aop:around method="runCommand" pointcut-ref="contactServiceTarget"/>
  14. </aop:aspect>
  15. </aop:config>
  16. <aop:config>
  17. <aop:aspect id="addressServiceAspect" ref="addressDaoCommand">
  18. <aop:pointcut id="addressServiceTarget"
  19. expression="execution(* com.xianlinbox.hystrix.dao.AddressDao.getAddress(..))"/>
  20. <aop:around method="runCommand" pointcut-ref="addressServiceTarget"/>
  21. </aop:aspect>
  22. </aop:config>

该示例的系统行为和前面直接使用HystrixCommand构建的时完全一样的。 
总结 
从全文涉及的内容中,不难看出Netflix构建了一个完整的Hystrix生态系统,这个生态系统让Hystrix非常易于上手,同时又有非常多的配置选项和高级用法来满足不同系统的个性化需求。对于这样的工具,相信每个开发者都会喜欢。另外,对于Netflix这样把自己的经验变成工具造福整个社区的行为,不由得不赞赏。

http://ningandjiao.iteye.com/blog/2171849

转载于:https://my.oschina.net/xiaominmin/blog/1599122

使用Hystrix守护应用(3)相关推荐

  1. 使用Hystrix守护应用(1)

    2019独角兽企业重金招聘Python工程师标准>>> 使用Hystrix守护应用(1) 博客分类: java 微服务 Hystrix(https://github.com/Netf ...

  2. Hystrix的一个坑,queue中的run方法没有被执行?

    今天学的时候随手测了一下Hystrix的queue的异步执行,发现执行queue之后,还没有打印run方法中的内容,程序就结束了: import com.netflix.hystrix.Hystrix ...

  3. hystrix 源码 线程池隔离_Spring Cloud Hystrix 源码学习合集

    # Spring Cloud Hystrix 源码学习合集 **Hystrix: Latency and Fault Tolerance for Distributed Systems** ![](h ...

  4. Python 多进程笔记 — 启动进程的方式、守护进程、进程间通信、进程池、进程池之间通信、多进程生产消费模型

    1 面向过程启动多进程 Python 操作进程的类都定义在 multiprocessing 模块,该模块提供了一个 Process 类来代表一个进程对象,这个对象可以理解为是一个独立的进程,可以执行另 ...

  5. 【微服务架构】SpringCloud之断路器(hystrix)

    说在前面 在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用.为了保证其高可用 ...

  6. 用 Hystrix 构建高可用服务架构

    1 hystrix是什么 在分布式系统中,每个服务都可能会调用很多其他服务,被调用的那些服务就是依赖服务,有的时候某些依赖服务出现故障也是很正常的. Hystrix 可以让我们在分布式系统中对服务间的 ...

  7. 5.1.14 守护线程

    守护进程与守护线程的区别: 守护进程:主进程代码运行完后,守护进程就终止. 守护线程:主进程运行完后,守护线程就终止.不过,如果主线程有多个线程的话, 其他线程未执行完,主线程就还在.守护线程会等主进 ...

  8. php 一秒操作一次_php守护进程 加linux命令nohup实现任务每秒执行一次

    Unix中 nohup 命令功能就是不挂断地运行命令,同时 nohup 把程序的所有输出到放到当前目录 nohup.out 文件中,如果文件不可写,则放到 /nohup.out 文件中.那么有了这个命 ...

  9. 【部署类】专题:消息队列MQ、进程守护Supervisor

    目录 1 背景需求 2 技术方案 2.1 消息队列 2.2 进程守护 3 源码介绍 3.1 supervisor部分 3.1.1 supervisord.conf 内容 3.1.2 MM3D.conf ...

最新文章

  1. Android Studio 选项菜单和动画结合_谷歌准备为Android增加像iOS一样的功能
  2. php和mysql的版本区别_MySQL各个版本区别_MySQL
  3. Internet上最危险的词语是什么?
  4. linux下vi编辑器常用命令
  5. 2017云栖大会:阿里巴巴宣布成立达摩院
  6. python 空格字符的表示_python字符串怎么去空格
  7. python y轴倒转_python – Config Kivy y轴的反转输入
  8. 用PHP玩百万英雄类型游戏!!!
  9. 大数据有哪些分析误区
  10. java cp命令:命令行指定需要加载的类classpath
  11. C#开发实战1200例(第II卷)目录
  12. shell 追加指定内容至某文件
  13. 喜报丨酷雷曼成功挂牌北京股权交易中心科技创新板
  14. 小样本学习只是一场学术界自嗨吗?
  15. 测试框架#labview
  16. 【ArcGIS】01 水文流域提取
  17. qrc路径_Windows下 Qt 资源文件(.qrc)文件 的 编写与应用
  18. js高级第四天(apply call bind以及闭包)
  19. es文件浏览器添加ftp服务器,es文件浏览器新建ftp服务器
  20. 【电子电路】开关电源输出电容大小和纹波电流有效值的计算

热门文章

  1. 《穿越计算机的迷雾》读书笔记二
  2. 汇编(8086cpu): AX,BX,CX,DX寄存器
  3. python四:字符串和数字
  4. vscode插件列表及配置信息
  5. GSON的使用以及GsonFormat工具的安装
  6. leetcode算法题01
  7. 面向对象的程序设计——理解对象
  8. 二十年后的回眸(5)——一部单车闯天下
  9. C++二维码相关库编译
  10. 【3】python核心编程 第六章-序列:字符串、列表和元组