SpringCloud学习之Hystrix
一、为什么要有断路器
在分布式系统当中,服务之间调用关系会随着业务的发展而变的复杂,一个服务可能依赖多个服务,服务之间层层依赖也是家常便饭的事情,如果一个服务的瘫痪很有可能导致整个系统的崩溃。比如说,现在每栋房子,每家每户都有电闸,电闸的作用是保证有一家用电出现异常时,电闸进行断电跳闸的操作,这样不至于导致整栋楼用电瘫痪,那么我们的系统也是如此:我们请看下图:



这个系统架构中由于服务I的异常(可能是程序运行错误,可能是系统阻塞,可能是负载过重等等),渐渐的导致整个系统崩溃,我们称之为雪崩效应
二、关于Hystrix
- Hystrix对应的中文名字是“豪猪”,豪猪周身长满了刺,能保护自己不受天敌的伤害,代表了一种防御机制,Hystrix提供了熔断、隔离、Fallback、cache、监控等功能,能够在一个、或多个依赖同时出现问题时保证系统依然可用。
- Hystrix通过四个方面的机制来解决这个问题
- 隔离(线程池隔离和信号量隔离):限制调用分布式服务的资源使用,某一个调用的服务出现问题不会影响其他服务调用。线程隔离:每个服务都为一个个独立的线程组,当I服务出现问题时,不会导致整个服务瘫痪。由于线程隔离会带来线程开销,有些场景(比如无网络请求场景)可能会因为用开销换隔离得不偿失,为此hystrix提供了信号量隔离,当服务的并发数大于信号量阈值时将进入fallback。
隔离策略示例图:

- 优雅的降级机制:超时降级、资源不足时(线程或信号量)降级,降级总之是一种退而求其次的方式,根据业务场景的不同,一般采用以下两种模式进行降级:第一种(最常用)如果服务失败,则我们通过fallback进行降级,返回静态值。第二种:调用备选方案
- 融断:当失败率达到阀值自动触发降级(如因网络故障/超时造成的失败率高),熔断器触发的快速失败会进行快速恢复。类似于电闸

- 缓存:提供了请求缓存、请求合并实现。
- 支持实时监控、报警、控制(修改配置)
三、Hystrix使用方法
3.1)继承HystrixCommand类,重写run方法与getFallBack方法,简单的代码示例:
package com.bdqn.lyrk.springcloud.order.hystrix; import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey; public class HelloWorldHystrix extends HystrixCommand<String> { public HelloWorldHystrix() {
super(HystrixCommandGroupKey.Factory.asKey("first"));
} @Override
protected String run() throws Exception {
//Thread.sleep(10000);
System.out.println("running...");
// System.out.println(1 / 0);
return "running...";
} @Override
protected String getFallback() {
System.out.println("error running...");
return "error running...";
}
}
3.2) 设置信号量隔离策略,初次接触设置属性的代码比较复杂,更多的可以参考wiki:
public HelloWorldHystrix() {
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("first"))
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
.withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE))
.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter().withQueueSizeRejectionThreshold(10))
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter().withExecutionIsolationSemaphoreMaxConcurrentRequests(10))
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter().withFallbackIsolationSemaphoreMaxConcurrentRequests(50))
);
}
3.3)针对于3.2,我们可以创建如下线程进行调用:
for (int i = 0; i < 50; i++) {
new Thread(() -> {
HelloWorldHystrix helloWorldHystrix = new HelloWorldHystrix();
helloWorldHystrix.execute();
}).start();
}
四。spring-cloud中使用Hystrix
4.1) 添加相关依赖
compile('org.springframework.cloud:spring-cloud-starter-hystrix')
compile('org.springframework.cloud:spring-cloud-starter-hystrix-dashboard')
4.2) 在启动类上添加 @EnableCircuitBreaker与@EnableHystrixDashboard注解
package com.bdqn.lyrk.springcloud.order; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard; @SpringBootApplication
@EnableEurekaServer
@EnableCircuitBreaker
@EnableHystrixDashboard
public class OrderApplication { public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
4.3)添加@HystrixCommand注解
package com.bdqn.lyrk.springcloud.order.controller; import com.bdqn.lyrk.service.api.IOrderService;
import com.bdqn.lyrk.service.dto.OrderDTO;
import com.bdqn.lyrk.springcloud.order.config.StudentConfig;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController; import java.util.concurrent.TimeUnit; @RestController
@RefreshScope
public class OrderController { @Autowired
private StudentConfig studentConfig; @Autowired
private IOrderService orderService; @GetMapping("/getInfo")
public String getInfo() {
return studentConfig.getName() + ":" + studentConfig.getAge();
} @GetMapping("/orderId/{orderId}")
@HystrixCommand(fallbackMethod = "getFailedOrder", commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
, @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "2")
})
public OrderDTO getOrderById(@PathVariable("orderId") Integer orderId) throws InterruptedException {
TimeUnit.SECONDS.sleep(orderId);
return orderService.getOrderById(orderId);
} public OrderDTO getFailedOrder(Integer orderId) {
OrderDTO orderDTO = new OrderDTO();
orderDTO.setOrderName("失败的订单");
return orderDTO;
}
}
注意其中有两个关键属性分别为:
execution.isolation.thread.timeoutInMilliseconds 这个是请求最大的响应时间
circuitBreaker.requestVolumeThreshold 如果执行失败的次数等于或者超过这个值就开启保护
4.4)当我们的系统添加actutator时,我们可以访问请求地址:http://localhost:8001/health 来检测状态

此时我们通过http://localhost:8001/orderId/4访问三次服务得到如下结果

注意,此时断路器打开保护机制
4.5)使用Hystrix的仪表盘
还记得我们添加 spring-cloud-starter-netflix-hystrix-dashboard的依赖么?通过访问http://localhost:8001/hystrix就可以得到如下界面

SpringCloud学习之Hystrix的更多相关文章
- SpringCloud学习(6)——Hystrix熔断器
分布式系统面临的问题 复杂的分布式体系结构中的应用程序有数十个依赖关系, 每个依赖关系在某些时刻不可避免的失败. 服务雪崩效应 多个微服务调用的时候, 假设微服务A调用微服务B和微服务C, 微服务B和 ...
- SpringCloud学习之Hystrix请求熔断与服务降级(六)
我们知道大量请求会阻塞在Tomcat服务器上,影响其它整个服务.在复杂的分布式架构的应用程序有很多的依赖,都会不可避免地在某些时候失败.高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险 ...
- SpringCloud学习之feign
一.关于feigin feigin是一种模板化,声明式的http客户端,feign可以通过注解绑定到接口上来简化Http请求访问.当然我们也可以在创建Feign对象时定制自定义解码器(xml或者jso ...
- SpringCloud学习系列之三----- 断路器(Hystrix)和断路器监控(Dashboard)
前言 本篇主要介绍的是SpringCloud中的断路器(Hystrix)和断路器指标看板(Dashboard)的相关使用知识. SpringCloud Hystrix Hystrix 介绍 Netfl ...
- SpringCloud学习笔记(4):Hystrix容错机制
简介 在微服务架构中,微服务之间的依赖关系错综复杂,难免的某些服务会出现故障,导致服务调用方出现远程调度的线程阻塞.在高负载的场景下,如果不做任何处理,可能会引起级联故障,导致服务调用方的资源耗尽甚至 ...
- SpringCloud学习笔记(5):Hystrix Dashboard可视化监控数据
简介 上篇文章中讲了使用Hystrix实现容错,除此之外,Hystrix还提供了近乎实时的监控.本文将介绍如何进行服务监控以及使用Hystrix Dashboard来让监控数据图形化. 项目介绍 sc ...
- SpringCloud学习之Ribbon
一.负载均衡与Ribbon 负载均衡,在集群中是很常见的一个“名词”,顾名思义是根据一定的算法将请求分摊至对应的服务节点上,常见的算法有如下几种: 轮询法:所有请求被依次分发到每台应用服务器上,每台服 ...
- SpringCloud中使用Hystrix
1. 引言 一般而言,一个服务都是部署了多台机器的,那么在这种情况下,当其中一个服务挂了以后Hystrix是怎么处理的呢? 为了验证这个问题,我们准备两个服务:user-api 和 app-gate ...
- SpringCloud学习系列之七 ----- Zuul路由网关的过滤器和异常处理
前言 在上篇中介绍了SpringCloud Zuul路由网关的基本使用版本,本篇则介绍基于SpringCloud(基于SpringBoot2.x,.SpringCloud Finchley版)中的路由 ...
随机推荐
- 再议Python协程——从yield到asyncio
协程,英文名Coroutine.前面介绍Python的多线程,以及用多线程实现并发(参见这篇文章[浅析Python多线程]),今天介绍的协程也是常用的并发手段.本篇主要内容包含:协程的基本概念.协程库 ...
- STM32F4系列单片机上使用CUBE配置MBEDTLS实现pem格式公钥导入
|版权声明:本文为博主原创文章,未经博主允许不得转载. 最近尝试在STM32F4下用MBEDTLS实现了公钥导入(我使用的是ECC加密),整个过程使用起来比较简单. 首先,STM32F4系列CUBE里 ...
- php代码一样,编码不同报错
php代码一样,编码不同报错 两个php代码完全一样,但是就报错,比如说声明比如在very first,这种,可以把编码设置utf-8 无bom
- dubbo的InvocationChain
个人觉得dubbo比较好的设计是:一个是Cooma微容器设计.另一个就是InvocationChain了 Cooma微容器是自己实现了一套SPI,方便了用户做扩展: InvocationChain类似 ...
- sql server 常用的查询语句
最近在加强sql 语句的学习,整理一下基本语法,现在记录下 select * from dbo.cangku where city='河南' select distinct(city), cangk ...
- java Servlet文件拷贝的模板代码
//通过response对象获得一个输出流对象 ServletOutputStream os = response.getOutputStream(); //获得要拷贝文件的绝对路径 String r ...
- A、B同时打开一个页面进行同一条数据库记录进行修改,A修改完成后提交表单,A修改的数据保存完成后;当B也修改完成后,提交数据进行数据修改。此时B修改的内容会覆盖A修改的内容,请问如何避免?
A.B同时打开一个页面进行数据中的一条数据进行修改,A修改完成后提交表单,数据修改保存完成后B开始页面也修改完成,开始提交进行修改.此时B修改的内容会覆盖A的内容,请问如何避免? 通过搜索和我个人总结 ...
- 最小二乘法多项式拟合的Java实现
背景 由项目中需要根据一些已有数据学习出一个y=ax+b的一元二项式,给定了x,y的一些样本数据,通过梯度下降或最小二乘法做多项式拟合得到a.b,解决该问题时,首先想到的是通过spark mllib去 ...
- 教你如何用AST语法树对代码“动手脚”
个推安卓工程师,负责公司移动端项目的架构和开发,主导移动端日志管理平台系统架构和开发工作,熟悉前后端的技术线,参与个推SDK主要业务研发工作,善于解决项目中遇到的痛点问题. 作为程序猿,每天都在写代码 ...
- 1028阿里RDS如何恢复云数据库MySQL的备份文件到自建数据库
参照 https://help.aliyun.com/knowledge_detail/41817.html 恢复云数据库MySQL的备份文件到自建数据库 更新时间:2017-07-27 14:52: ...