Hystrix学习
Hystrix学习
概述
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时,异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性
“断路器”本身是一种开关设置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的,可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要的占用,从而避免了故障在分布式系统中蔓延,乃至雪崩。
Hystrix能干哪些事?
-
服务熔断(break)
比如系统达到最大访问量的时候,直接拒绝访问,拉闸限电,然后调用服务降级的方法并返回友好提示!
-
服务降级(fallback)
当程序运行异常、超时、服务熔断触发降级、线程池/信号量打满导致服务降级的时候,通过服务器忙,请稍后重试,不让客户端等待并立刻返回一个友好的提示!
-
接近实时的监控
-
限流(flowlimit)
秒杀高并发操作,严禁一窝蜂的过来拥挤,大家排队,一秒钟N个,有序进行
服务降级实操及应用场景
触发场景
比如程序运行异常、超时、服务宕机等都要进行服务降级
依赖添加
<dependencies>
<!--引用工具模块-->
<dependency>
<groupId>com.lwp</groupId>
<artifactId>mz-common</artifactId>
</dependency>
<!--服务降级熔断hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<!--因为在springcloud2020.0.3版本netflix已经被移除,所以需要显示的添加依赖-->
<version>2.2.6.RELEASE</version>
</dependency>
<!--Eureka Client依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
服务提供者定义超时或者报错方法
@Service
public class PaymentService {
/**
* 测试超时或者报错的方法是否会进入服务降级
* @return
*/
@HystrixCommand(fallbackMethod = "testTimeoutOrErrorHandle", //降级处理方法
commandProperties = { //降级超时策略,更多策略官网:https://gitee.com/nilera/Hystrix/wikis/Configuration?sort_id=2684424
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="3000")
}
)
public String testTimeoutOrError(String id){
int time = 5;
try {
TimeUnit.SECONDS.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
//int a=10/0; //注释上面线程睡眠方法测试报错降级,同样成功降级
return "当前线程:"+Thread.currentThread().getName()+"\t"+"成功!"+id;
}
/**
* 服务降级方法
* @param id
* @return
*/
private String testTimeoutOrErrorHandle(String id){
return "当前线程:"+Thread.currentThread().getName()+"\t"+"降级成功!"+id;
}
}
启动类添加注解开启降级服务
@SpringBootApplication
@EnableHystrix //启用Hystrix,旧版本使用@EnableCircuitBreaker注解启用
public class HystrixPaymentMain8001 {
public static void main(String[] args) {
SpringApplication.run(HystrixPaymentMain8001.class,args);
}
}
默认全局降级定义
如果每个方法去定义服务降级,容易造成代码膨胀以及业务混乱,这时候我们可以通过全局默认服务降级进行配置,使没有定义降级方法的进入全局降级方法,只有特殊业务处理的才进入自定义的降级方法
实现
@Service
//定义全局默认降级
@DefaultProperties(defaultFallback="defaultGlobalHandle")
public class PaymentService {
/**
* 测试超时或者报错的方法是否会进入服务降级
* @return
*/
@HystrixCommand(fallbackMethod = "testTimeoutOrErrorHandle", //降级处理方法
commandProperties = { //降级超时策略,更多策略官网:https://gitee.com/nilera/Hystrix/wikis/Configuration?sort_id=2684424
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="3000")
}
)
public String testTimeoutOrError(String id){
// int time = 2;
// try {
// TimeUnit.SECONDS.sleep(time);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
int a=10/0; //测试报错降级
return "当前线程:"+Thread.currentThread().getName()+"\t"+"成功!"+id;
}
/**
* 特定服务降级方法
* @param id
* @return
*/
private String testTimeoutOrErrorHandle(String id){
return "当前线程:"+Thread.currentThread().getName()+"\t"+"降级成功!"+id;
}
@HystrixCommand //该注解一定要加才能交由hystrix管理,触发默认降级方法
public String testGlobal(){
int a = 2/0;
return "呵呵!";
}
/**
* 默认全局降级处理方法
* @return
*/
public String defaultGlobalHandle(){
return "全局降级处理方法----";
}
}
OpenFeign+Hystrix实现服务降级
yaml配置启用OpenFeign+Hystrix
feign:
# hystrix: cloud2020版本之前使用,之后使用circuitbreaker
circuitbreaker:
enabled: true #开启支持
OpenFeign服务接口编写
@Component
//value:服务名称,fallback:服务降级处理类
@FeignClient(value = "HYSTRIX-SERVICE-PAYMENT",fallback = PaymentOpenFeignImpl.class)
public interface PaymentOpenFeign {
@RequestMapping("/payment/test/{id}")
public AjaxResult test(@PathVariable("id") String id);
}
OpenFeign降级类定义
@Component
public class PaymentOpenFeignImpl implements PaymentOpenFeign{
@Override
public AjaxResult test(String id) {
return AjaxResult.error("请求的服务器以宕机,请稍后重试!");
}
}
测试结论
当访问消费端服务时,服务提供者如果正常提供服务,返回服务提供者的信息,如果服务提供者宕机或者异常,返回OpenFeign指定的实现类来处理服务降级
注意:如果OpenFeign开启Hystrix支持失败,为hystrix版本太低,比如我对2.1.6.RELEASE测试开启支持失败,升级到2.2.6.RELEASE便可以使用
降级理解
服务端提供者和消费者都可以进行服务降级,一般服务降级放在客户端
服务熔断实操及应用场景
熔断机制描述
熔断机制是应对雪崩效应的一种微服务链路保护机制,当扇出链路的某个微服务出错不可用或者响应时间太长,会进行服务降级,进而熔断该节点微服务的调用,快速返回错误的响应消息。
在Spring Cloud框架中,熔断机制通过Hystrix实现,Hystrix会监控微服务之间的调用状况,当失败的调用达到一定的阈值,缺省是5秒内调用失败20次,就会启动熔断机制,熔断机制的注解是@HystrixCommand
牛逼点:当检测到该节点微服务调用响应正常后,恢复调用链路
代码实操
service添加方法测试
@Service
public class PaymentService {
//------------------服务熔断------------
//更多的@HystrixCommand属性设置查看HystrixCommandProperties类
@HystrixCommand(fallbackMethod = "testRdHandle",commandProperties = {
//启用断路器
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
//设置请求次数
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
//设置时间窗口期
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),
//设置失败率,失败率达到设定的值触发熔断
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")
})
public String testRd(Integer age){
if(age>18){
throw new RuntimeException("年龄太大");
}
return "年龄刚刚好!";
}
private String testRdHandle(Integer age){
return "年龄太大,服务降级处理!";
}
}
控制层添加方法测试
@RestController
@RequestMapping("/payment")
public class PaymentController {
@Autowired
private PaymentService paymentService;
/**
* 熔断测试
* @param age 年龄阈值
* @return
*/
@RequestMapping("/testRd/{age}")
public AjaxResult testRd(@PathVariable("age") Integer age){
return AjaxResult.success(paymentService.testRd(age));
}
}
测试结论
//更多的@HystrixCommand属性设置查看HystrixCommandProperties类
@HystrixCommand(fallbackMethod = "testRdHandle",commandProperties = {
//启用断路器
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
//设置请求次数
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
//设置时间窗口期
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),
//设置失败率,失败率达到设定的值触发熔断
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")
})
根据以上策略,我们只需要在10秒内,请求10次,错误率达到百分之60就会触发熔断机制,一旦熔断机制触发,断路器开启,这时候我们哪怕发生正确的请求,响应的也是服务降级的处理方法,在一段时间后(默认5秒)断路器处于半开状态,尝试将请求转发,如果得到正确的响应。则将断路器关闭,恢复正常调用!
Hystrix DashBoard监控搭建
依赖添加
<dependencies>
<!--导入 hystrix 与 hystrix-dashboard 依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>com.lwp</groupId>
<artifactId>mz-common</artifactId>
</dependency>
</dependencies>
配置文件创建
server:
port: 9001
服务启动
@SpringBootApplication
@EnableHystrixDashboard //开启服务监控
public class HystrixDashboardMain9001 {
public static void main(String[] args) {
SpringApplication.run(HystrixDashboardMain9001.class,args);
}
}
服务监控
服务启动后访问:http://127.0.0.1:9001/hystrix
被监控的服务暴露端点
主启动类添加Bean
@SpringBootApplication
@EnableHystrix //启用Hystrix,旧版本使用@EnableCircuitBreaker注解启用
public class HystrixPaymentMain8001 {
public static void main(String[] args) {
SpringApplication.run(HystrixPaymentMain8001.class,args);
}
/**
* 暴露监控流
* @return
*/
@Bean
public ServletRegistrationBean hystrixMetricsStreamServlet() {
ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
registrationBean.addUrlMappings("/actuator/hystrix.stream");
return registrationBean;
}
}
代码参考
hystrix-payment-8001
hystrix-order-90
hystrix-dashboard-9001

浙公网安备 33010602011771号