展开
拓展 关闭
订阅号推广码
GitHub
视频
公告栏 关闭

Hystrix

在分布式微服务中,通常是一个服务调用另一个服务,在我们进行某种操作时,就造成了一个很长的服务链路调用,这时如果其中某一个服务出现故障,整个系统就会崩溃,也就是雪崩

为了解决这些问题,提高系统的弹性,可用HyStrix的服务降价、服务熔断、服务限流来解决这些问题

服务降级(fallback):当(程序运行异常、超时、服务熔断触发降级、线程池/信号量)等情况导致服务降级时,返回一个友好的提示或者给一个兜底的方案,不至于程序一直拥堵或崩溃
服务熔断(break):当服务访问达到最大访问量时,为了防止程序崩溃,会直接拒绝请求
服务限流(flowlimit):在规定时间内限制一定数量的服务访问,使服务访问有序进行

服务访问过多的测试案例:
1. 新建cloud-provider-hystrix-payment8001支付子模块,pom中添加hystrix依赖,yml中配置端口和项目名称,编写启动类,编写业务,业务层编写两个方法,一个模拟正常访问,一个模拟超时访问,控制层调用业务层
2. 测试控制层接口,正常访问的是立即响应,超时访问的是3秒后响应
3. 使用JMeter测试,发送20000个请求访问超时的接口,同时访问正常的接口时,响应也变慢了
4. 新建cloud-consumer-feign-hystrix-order80订单子模块,配置pom引入HyStrix依赖、yml、启动类、业务类,这个微服务作为消费者使用OpenFeign调用cloud-provider-hystrix-payment8001提供者微服务
5. 再次使用JMeter发送20000个并发请求访问8001的超时接口,同时访问80模块的接口,发现80模块的响应变慢了
6. 结论:当访问超时方法过多时,同层次的其他访问会被困死,其他服务调用该服务时也会缓慢、超时等
  • 对8001模块进行降级处理:
在超时方法中会模拟超时5秒,@HystrixCommand指定了超时后用于兜底的方法和最大超时时间;编写用于兜底的方法

启动类上添加注解@EnableCircuitBreaker用于激活降级处理的注解
测试:访问超时的方法,模拟超时的时间超过了最大时间,需做降级处理,转而执行备用的方法
当超时或者出现异常时,都会转而去执行备用的方法
  • 对80订单模块进行降级处理:
服务的提供者和消费者都可使用服务降级,通常是在消费端使用;这里将8001模块的超时方法设置为未超时用于测试
配置pom、yml,主启动类添加@EnableHystrix
编写业务,指定兜底的方法,和最大超时时间

测试:8001模拟的超时时间是3秒,没有超过8001最大时间5秒,但80模块最大超时时间是1.5秒,需做服务降级,执行兜底方法
idea设置了热部署对Java代码敏感,对注解内的属性修改不敏感,需自行重启服务
  • 解决代码膨胀:
问题描述:例如在80模块中对服务进行降级处理,有一个方法,就需要做一次降级,代码耦合度变高
解决方案:在80模块的控制层中,@DefaultProperties(defaultFallback="")指定一个全局兜底的方法,在方法上添加@HystrixCommand;那么这个方法需降级处理时会执行全局兜底的方法;需要特别处理的方法再使用以上的方式

  • 解决业务混乱:
问题描述:当80去调8001时,8001出现运行异常、宕机、超时等,这个80该如何进行服务降级处理
解决方案:80模块的业务逻辑是控制层调OpenFeign,OpenFeign调8001;这里实现OpenFeign接口,在控制层中指定实现类
yml中配置HyStrix与OpenFeign的整合配置

测试:访问80模块控制层的接口,通常情况下通过@FeignClient中指定的名称找到8001模块,去调8001的方法,当序号1出故障后,则执行序号2兜底的方法;即是当8001服务停用后,会转而执行OpenFeign实现类
  • 服务熔断和降级的区别:
降级是出现异常时返回一个错误或执行备用的方法,熔断则是访问过多时服务的降级  ->  进而熔断  ->  恢复调用链路
  • 熔断的工作流程:
当访问过大时进行服务熔断,从closed变成open状态
当再次有少量请求时,变成halfOpen(半关闭状态)
当少量请求处理完后,变成closed状态

  • 服务熔断案例:
修改cloud-provider-hystrix-payment8001模块中的业务层,编写一个方法,当参数为正数则正常执行,为负数或异常、超时等则执行兜底的方法,服务熔断的配置表示:启动熔断,指定时间内,10次请求中错误或超时的情况达到60%则进行服务熔断

8001模块中控制层调用业务层方法
测试:访问http://localhost:8001/payment/circuit/31时正常执行,访问http://localhost:8001/payment/circuit/-31时会执行兜底的方法,当10次中有6次错误时,也就变成了open状态,这时即使是正数参数,也会执行兜底方法,再多执行几次正数参数,错误百分比低于十分之六时又可以正常执行了
  • 服务监控:
新建cloud-consumer-hystrix-dashboard9001子模块作为监控平台
pom中引入依赖hystrix dashboard,yml中配置端口,启动类添加注解@EnableHystrixDashboard
例如我们在8001模块中使用服务降级或服务熔断,当我们使用9001监控8001时,8001需拉取依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

同时8001的启动类需做如下修改
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker  //激活hystrix
public class PaymentHystrixMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentHystrixMain8001.class,args);
    }
    /**
     * 此配置是为了服务监控而配置,与服务容错本身无关,springcloud升级后的坑
     * ServletRegistrationBean因为springboot的默认路径不是/hystrix.stream
     * 只要在自己的项目里配置下面的Servlet就可以了
     */
    @Bean
    public ServletRegistrationBean getServlet() {
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }
}

启动9001模块,浏览器输入:http://localhost:9001/hystrix   可访问hystrix监控页面;填写要监控的8001

浏览器访问http://localhost:8001/payment/circuit/31和http://localhost:8001/payment/circuit/-31;再返回hystrix监控页面点击监控按钮即可查看服务信息

posted @ 2022-07-27 11:00  DogLeftover  阅读(23)  评论(0编辑  收藏  举报