一、概述
1、服务雪崩
多个微服务之间调用的时候,假设微服务A调用微服务B和C,微服务B和C又调用其他的微服务,这就是所谓的“扇出”。
如果扇出的链路上某个微服务的调用响应时间过长或者不可用,那么对微服务的调用就会占用越来越多的系统资源,从而引起系统崩溃,这就是所谓的"雪崩效应“
对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源在几秒内饱和。比失败更糟糕的是这些应用程序还可能导致服务之间的延迟增加,备份队列、线程和其他系统资源紧张,导致整个系统发生更多的级联故障。这些都预示着需要对故障和延迟进行隔离和管理,以便单个依赖的失败不能取消整个应用或者系统
2、Hystrix 是什么
二、Hystrix重要概念
1、服务降级
服务器忙,请稍后再试,不让服务器等待,并立即返回一个友好提示 fallback
哪些情况会触发服务降级?
① 程序运行异常
② 超时
③ 服务熔断触发服务降级
④ 线程池、信号量打满触发服务降级
2、服务熔断
达到最大服务访问后,直接拒绝访问,然后用服务降级的方式返回友好的提示
【注意】服务熔断后,会在请求并发量减少时,自动恢复链路
3、服务限流
秒杀高并发等操作,严禁一窝蜂的过来拥挤,大家排队,一秒钟N个,有序进行
三、Hystrix 案例实现
1、搭建服务提供者端:cloud-provider-hystrix-payment8001
① pom文件
<dependencies>
<!--hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!--eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--web-->
<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>
<dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
<groupId>com.atguigu.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
② yml文件
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,http://eureka7002.com:7002/eureka
defaultZone: http://eureka7001.com:7001/eureka
③ 主启动类
@SpringBootApplication
@EnableDiscoveryClient
public class PaymentHystrixMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentHystrixMain8001.class,args);
}
}
④ 业务类 :
@RestController
@Slf4j
public class PaymentController {
@Autowired
private PaymentService paymentService;
@Value("${server.port}")
private String serverPort;
@GetMapping("/payment/hystrix/ok/{id}")
public String paymentInfo_ok(@PathVariable("id") Integer id){
String result = paymentService.paymentInfo_ok(id);
log.info("*****************result************");
return result;
}
@GetMapping("/payment/hystrix/timeout/{id}")
public String paymentInfo_timeout(@PathVariable("id") Integer id) throws InterruptedException {
String result = paymentService.paymentInfo_timeout(id);
log.info("*****************result************");
return result;
}
}
@Service
public class PaymentService {
public String paymentInfo_ok(Integer id){
return "线程池:"+Thread.currentThread().getName()+
" paymentInfo_ok,id:"+id+" O(∩_∩)O哈哈~";
}
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+" 耗时3秒!!";
}
}
⑤、jmeter压力测试
开启Jmeter,20000个并发,压测http://localhost:8001/payment/hystrix/timeout/1 接口,
然后去浏览器上访问 http://localhost:8001/payment/hystrix/timeout/1
访问会出现卡顿
2、服务消费方80加入 cloud-consumer-feign-hystrix-order80
①、pom文件 : 主要是hytrix和feign的依赖
<dependencies>
<!--openfeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!--eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
<dependency>
<groupId>com.atguigu.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!--web-->
<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>
<!--一般基础通用配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
②、yml
server:
port: 80
spring:
application:
name: cloud-consumer-order
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka
③、主启动类
@SpringBootApplication
@EnableFeignClients
public class ConsumerFeignHystrixMian80 {
public static void main(String[] args) {
SpringApplication.run(ConsumerFeignHystrixMian80.class,args);
}
}
④、业务类
@RestController
@Slf4j
public class OrderController {
@Autowired
private PaymentHystrixService paymentHystrixService;
@GetMapping("/consumer/payment/hystrix/ok/{id}")
public String paymentInfo_ok(@PathVariable("id") Integer id)
{
String result = paymentHystrixService.paymentInfo_ok(id);
return result;
}
@GetMapping("/consumer/payment/hystrix/timeout/{id}")
public String paymentInfo_timeout(@PathVariable("id") Integer id)
{
String result = paymentHystrixService.paymentInfo_timeout(id);
return result;
}
}
=========================================================================================
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT")
public interface PaymentHystrixService {
@GetMapping("/payment/hystrix/ok/{id}")
public String paymentInfo_ok(@PathVariable("id") Integer id);
@GetMapping("/payment/hystrix/timeout/{id}")
public String paymentInfo_timeout(@PathVariable("id") Integer id);
}
⑤、访问 http://localhost/consumer/payment/hystrix/ok/1 ,显示下图,说明远程调用成功
⑥、
开启Jmeter,20000个并发,压测http://localhost:8001/payment/hystrix/timeout/1 接口,
然后去浏览器上访问 http://localhost/consumer/payment/hystrix/ok/1
访问会出现卡顿
3、上述结论
正是有了上述故障或不假表现,才有了我们降级、容错,限流的技术的产生
4、如何解决
① 服务提供方超时,调用者80不能一直卡死等待,必须要有服务降级
② 服务提供方宕机了,调用者不能一直处于卡死状态,必须要有服务降级
③ 服务提供者ok,调用者80自己出故障,自己要有服务降级