文章目录
系列链接:
- GitHub:源码
- SpringCloud(1)–入门、版本、环境搭建
- SpringCloud(2)–服务注册与发现(Eureka、Zookeeper、Consul)
- SpringCloud(3)–服务调用(Ribbon、OpenFeign)
- SpringCloud(4)–服务降级(Hystrix、降级、熔断、监控)
- SpringCloud(5)–服务网关(GateWay)
- …
服务降级
首先需要了解一个概念,服务雪崩:
多个微服务之间调用时,假设微服务 A 调用微服务 B 和微服务 C,微服务 B 和微服务 C 又调用其它的微服务,这就是所谓的”扇出“。如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务 A 的调用就会占用越来越多的系统资源,进而导致系统”雪崩效应“。
Hystrix
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,它能够保证在一个依赖出现问题的情况下,不会导致整体服务失败,避免级联故障(雪崩)。
主要作用
- 服务降级:比如当某个服务繁忙,不能让客户端的请求一直等待,应该立刻返回给客户端一个备选方案。
- 服务熔断:当某个服务出现问题,卡死了,不能让用户一直等待,需要关闭所有对此服务的访问然后调用服务降级。
- 服务限流:比如秒杀场景,不能访问用户瞬间都访问服务器,限制一次只可以有多少请求。
- 接近实时的监控
Hystrix
服务降级
比如当某个服务繁忙,不能让客户端的请求一直等待,应该立刻返回给客户端一个备选方案。
出现降级的情况:
- 程序运行异常
- 超时
- 发生服务熔断
- 线程池/信号量打满
创建带降级机制的pay模块
-
名称: cloud-provider-hystrix-payment8001
-
pom文件
<!-- hystrix--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
-
配置文件,为了减少资源占用,这里使用单机版 Eureka
server: port: 8001 spring: application: name: cloud-provider-hystrix-payment eureka: client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://eureka7001.com:7001/eureka # defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
-
主启动类
@SpringBootApplication @EnableEurekaClient public class PaymentHystrixMain8001 { public static void main(String[] args){ SpringApplication.run(PaymentHystrixMain8001.class,args); } }
-
service,节约时间不写接口
@Service public class PaymentService { /* 正确的方法 */ public String paymentInfo_OK(Integer id){ return "线程池:"+Thread.currentThread().getName()+" paymentInfo_OK,id:"+id+"\t"+"???"; } /* 会超时报错的方法 */ public String paymentInfo_TimeOut(Integer id){ int timeNumber = 5; try{ TimeUnit.SECONDS.sleep(timeNumber); } catch (InterruptedException e) { e.printStackTrace(); } return "线程池:"+Thread.currentThread().getName()+" paymentInfo_TimeOut,id:"+id+"\t"+"!!!"; } }
-
controller
@RestController @Slf4j @RequestMapping("/payment") public class PaymentController { @Resource private PaymentService paymentService; @Value("${server.port}") private String serverPort; @GetMapping("/hystrix/ok/{id}") public String paymentInfo_OK(@PathVariable("id") Integer id){ St