SpringCloud系列(三)服务降级 您所在的位置:网站首页 16spro降级 SpringCloud系列(三)服务降级

SpringCloud系列(三)服务降级

#SpringCloud系列(三)服务降级| 来源: 网络整理| 查看: 265

这是我参与更文挑战的第 13 天,活动详情查看: 更文挑战

Hystrix 一、概述

Hystrix是一个用于分布式系统的延迟和容错的开源库,在分布式系统中,许多依赖会不可避免的调用失败,Hystrix能够在保证在一个依赖出问题的情况下,不会影响到整体的服务失败,避免联级故障,提高发生系统的弹性。

问题引出

多个微服务之间的调用会形成一个链路,当链路上的某个微服务发生故障失效(超时、异常等),这个有问题的模块再去调用其他模块,这样就会发生级联故障,也叫雪崩。

解决问题

'断路器'是一种开关装置,当某个服务发生故障时,通过断路器的故障监控,向调用方返回一个符合预期的、可处理的备选方案,而不是长时间的等待或抛出异常,保证了服务调用放的线程不会被长期不必要的占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。

Hystrix的功能:

服务降级:在程序运行异常、超时、线程池\信号量打满的情况下会触发降级,给客户端一个友好的提示,fallback。 服务熔断:类似保险丝,达到最大访问量后直接拒绝访问,然后调用访问降级给出友好提示。 服务限流:秒杀高并发操作,防止一窝蜂的访问访问,设置每秒执行多上个请求,超出的请求进行排队。 实时监控 二、服务降级 1、单侧降级

依赖

org.springframework.cloud spring-cloud-starter-netflix-hystrix 复制代码

配置

server: port: 80 eureka: client: register-with-eureka: false service-url: defaultZone: http://eureka7001.com:7001/eureka feign: hystrix: enabled: true 复制代码

Order80服务调用8001提供的服务,其中有一个延迟的接口

@Service public class PaymentService { public String paymentInfoSuccess(Integer id){ return "线程池:" + Thread.currentThread().getName() + " paymentInfoSuccessId:" + id; } public String paymentInfoFailed(Integer id){ //制造超时错误 try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } return "线程池:" + Thread.currentThread().getName() + " paymentInfoFailedId:" + id; } } 复制代码

因为OpenFeign的默认等待时间为1秒,所以调用超过1秒的接口会抛出异常,这样后面的服务可能都会因为这个延迟而故障,接下来添加服务降级功能解决问题。 降级配置,设置一个兜底方案。

提供服务8001模块异常后的fallback

@Service public class PaymentService { //fallbackMethod:指定兜底方法,commandProperties指定出现哪些异常进行fallbackMethod @HystrixCommand(fallbackMethod = "paymentInfoFailedHandler",commandProperties = { //如果超时3秒就执行fallbackMethod @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000") }) public String paymentInfoFailed(Integer id){ //制造超时错误 try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } return "线程池:" + Thread.currentThread().getName() + " paymentInfoFailedId:" + id; } public String paymentInfoFailedHandler(){ return "Payment8001的paymentInfoFailed的fallbackMethod执行了"; } } 复制代码

消费者Order80配置fallback,通常在消费者端配置

@RestController public class OrderHystrixController { @Resource private PaymentHystrixService paymentHystrixService; @HystrixCommand(fallbackMethod = "paymentInfoFailedHandler",commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000") }) @GetMapping(value = "/consumer/paymentInfoFailed/{id}") public String paymentInfoFailed(@PathVariable("id") Integer id) { return paymentHystrixService.paymentInfoFailed(id); } @GetMapping(value = "/consumer/paymentInfoSuccess/{id}") public String paymentInfoSuccess(@PathVariable("id") Integer id) { return paymentHystrixService.paymentInfoSuccess(id); } public String paymentInfoFailedHandler(){ return "Order80的paymentInfoFailed的fallbackMethod执行了"; } } 复制代码 2、全局降级

上面的情况会把fallback代码和业务代码耦合在一起,并且每一个方法都要单独设置一个fallback方法,用起来并不方便,使用全局的fallback来改进。

使用全局降级

@RestController //指定全局降级的fallback方法 @DefaultProperties(defaultFallback = "payment_Global_RollbackMethod") public class OrderHystrixController { @Resource private PaymentHystrixService paymentHystrixService; //开启全局降级,如果指定了fallback方法就使用已指定的,没有指定就使用全局的 @HystrixCommand @GetMapping(value = "/consumer/paymentInfoFailed/{id}") public String paymentInfoFailed(@PathVariable("id") Integer id) { return paymentHystrixService.paymentInfoFailed(id); } public String payment_Global_RollbackMethod() { return "Order80的paymentInfoFailed的payment_Global_RollbackMethod执行了"; } } 复制代码 3、通配服务降级

消费端在远程调用提供服务的接口时对其进行降级,如果提供服务的服务器发生宕机,也能降级成功。

创建一个类,实现远程调用的接口

@Component public class PaymentFallbackService implements PaymentHystrixService { @Override public String paymentInfoFailed(Integer id) { return "PaymentFallbackService的PaymentFallbackService fallback 方法"; } @Override public String paymentInfoSuccess(Integer id) { return "PaymentFallbackService 的paymentInfoSuccess fallback 方法"; } } 复制代码

在远程调用的接口上注明降级的类

@Component @FeignClient(name = "CLOUD-PAYMENT-HYSTRIX-SERVICE",fallback = PaymentFallbackService.class) public interface PaymentHystrixService { @GetMapping(value = "/paymentInfoFailed/{id}") String paymentInfoFailed(@PathVariable("id") Integer id); @GetMapping(value = "/paymentInfoSuccess/{id}") String paymentInfoSuccess(@PathVariable("id") Integer id); } 复制代码 三、服务熔断

熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务出错或不可用时,会进行服务降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。当检测到该节点微服务响应正常后,恢复链路调用。 SpringCloud中使用Hystrix实现熔断机制,Hystrix会监控微服务之间的调用状况,当失败的调用到一定的y阈值,就会启用熔断机制。

在payment8001服务中配置测试,在Service中配置熔断

@Service public class PaymentService { @HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",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 paymentCircuitBreaker(Integer id){ if (id < 0) { throw new RuntimeException("id 不能小于0"); } String uuid = IdUtil.simpleUUID(); return Thread.currentThread().getName() + "\t" + "SUCCESS,code:" + uuid; } public String paymentCircuitBreaker_fallback(Integer id){ return "id不能为负数,请稍后再试!" + id; } } 复制代码

该方法在10秒钟之内访问次数达到10次以上并且失败率如果达到百分之60,id传入负数,就会启动熔断机制(熔断器全开),这时即使发送的id为整数,也还是会继续走fallback方法(熔断器半开状态),稍等一会就会恢复正常的调用(熔断器关闭)。 熔断器状态:

熔断打开:请求不再调用当前服务,内部设置时钟(平均故障处理时间),当打开时间达到时钟所设时间进入半开状态。 熔断半开:部分请求根据规则调用当前服务,如果请求成功且符合规则认为当前服务恢复正常,关闭熔断。 熔断关闭:不会对服务进行熔断 四、服务监控

除了上述功能,Hystrix还提供的准实时的调用监控,Hystrix会持续的记录所有通过Hystrix发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行成功、失败多少次。

1、搭建dashboard9001服务

依赖

org.springframework.cloud spring-cloud-starter-netflix-hystrix-dashboard org.springframework.boot spring-boot-starter-actuator 复制代码

主启动

@SpringBootApplication @EnableHystrixDashboard public class DashboardMain9001 { public static void main(String[] args) { SpringApplication.run(DashboardMain9001.class,args); } } 复制代码

启动9001,访问http://localhost:9001/hystrix即可看到Hystrix Dashboard的主页

2、使用Dashboard监控服务

注意:在被监控的8001端主启动类需要加一个配置,springCloud升级后导致的

@SpringBootApplication @EnableEurekaClient @EnableCircuitBreaker public class PaymentHystrixMain8001 { public static void main(String[] args) { SpringApplication.run(PaymentHystrixMain8001.class,args); } @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; } } 复制代码

监控8001服务

在hystrix主页输入监控地址http://localhost:8001/hystrix.stream



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有