1、用户去请求A服务,A的tomcat会分配一个线程去支持用户的访问,A发现需要完成用户的操作,需要去调用B,
2、A去请求B,B的tomcat也会分配一个线程去支持A的访问。B发现需要完成A的操作,需要去调用C
3、B去调用C,但是C宕机了,B并不知道,一如既往的去访问c
导致A和B的线程都没有回收,此时有大量请求进入A服务或者B服务,AB会报错 503 sevrvice unavaliable
在分布式的链路中,只要有一个服务宕机,那么就可能导致一整个业务线都瘫痪
**本质:线程没有及时回收
服务雪崩的解决方法熔断:(保险丝)直接return,业务不能完成,但是可以缓解服务器压力
解决办法:
1、调整等待时间,这样可以缓解压力 (很有局限性。不是很灵活,有的服务需要很长时间去执行)
2、(拦截器)在上游服务提前知道前一个服务的状态,如果正常则访问,宕机则return,这样就可以缓解服务雪崩
我们可以容忍服务挂掉,但是需要做对应的策略可以设置一个备选方案
用户希望业务可以正常完成,
作为开发人员来讲,要保证其他的服务可以用
spring cloud Hystrix熔断器,也叫断路器!(正常情况下 断路器是关的 只有出了问题才打开)用来保护微服务不雪崩的方法。思想和我们上面画的拦截器一样。 Hystrix 是Netflix 公司开源的一个项目,它提供了熔断器功能,能够阻止分布式系统中出现联动故障。
Hystrix 是通过隔离服务的访问点阻止联动故障的,并提供了故障的解决方案,从
而提高了整个分布式系统的弹性。微博 弹性云扩容 Docker K8s
当有服务调用的时候,才会出现服务雪崩,所以 Hystrix 常和 OpenFeign,Ribbon 一起出现
在服务消费者(客户端加入Hystrix的依赖)
代码实现 服务消费者(客户端)application.java
package indi.yuluo.customerservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class CustomerServiceApplication {
public static void main(String[] args) {
SpringApplication.run(CustomerServiceApplication.class, args);
}
}
pom.xml
4.0.0 org.springframework.boot spring-boot-starter-parent 2.3.12.RELEASE indi.yuluo customer-service 0.0.1-SNAPSHOT 01-customer-service 01-customer-service 1.8 Hoxton.SR12 org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-hystrix org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.cloud spring-cloud-starter-openfeign org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} pom import org.springframework.boot spring-boot-maven-plugin
application.yml
server:
port: 9091
spring:
application:
name: customer-servie
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
instance:
hostname: localhost
prefer-ip-address: true
instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
# 开启Hystrix的功能
# 在spring的F版本以前,默认是开启的,F版本之后,关闭(因为有了其他的熔断组件)
feign:
hystrix:
enabled: true
controller
package indi.yuluo.customerservice.controller;
import indi.yuluo.customerservice.feign.CustomerRentCarFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CustomerController {
// 注入feign的接口
// 注意:在这的时候需要在启动类上加一个@EnableFeignClients的注解来开启feign接口的功能
@Autowired
private CustomerRentCarFeign customerRentCarFeign;
@GetMapping("/customerRent")
public String customerRent() {
System.out.println("客户来租车了!");
// 使用feign调用远程接口
String rent = customerRentCarFeign.rendCar();
return rent;
}
}
feign
package indi.yuluo.customerservice.feign;
import indi.yuluo.customerservice.feign.hystrix.CustomerRentCArFeignHystrix;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient(value = "rent-car-service", fallback = CustomerRentCArFeignHystrix.class)
public interface CustomerRentCarFeign {
// 写的是需要rpc调用的远程方法签名
@GetMapping("/rent")
String rendCar();
}
feign里的Hystrix子包
package indi.yuluo.customerservice.feign.hystrix;
import indi.yuluo.customerservice.feign.CustomerRentCarFeign;
import org.springframework.stereotype.Component;
@Component
public class CustomerRentCArFeignHystrix implements CustomerRentCarFeign {
@Override
public String rendCar() {
return "我是备选方案";
}
}
feign里面的Hystrix实现类的作用是提供备选方案,就是在服务提供者宕机之后的选择方案
服务提供者(服务端)1、在feign中建立hystrix
2、在hystrix中建立feign接口的实现类
3、加入@Component,将类交给spring容器进行管理,否则找不到bean
3、重写feign接口里的方法,提供备选方案
application.java
package indi.yuluo.rentcarservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class RentCarServiceApplication {
public static void main(String[] args) {
SpringApplication.run(RentCarServiceApplication.class, args);
}
}
pom.xml
4.0.0 org.springframework.boot spring-boot-starter-parent 2.3.12.RELEASE indi.yuluo rent-car-service 0.0.1-SNAPSHOT 02-rent-car-service 02-rent-car-service 1.8 Hoxton.SR12 org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} pom import org.springframework.boot spring-boot-maven-plugin
controller
package indi.yuluo.rentcarservice.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class RentCarController {
@GetMapping("/rent")
public String rendCar() {
return "租车成功!";
}
}
application.yml
server:
port: 9090
spring:
application:
name: rent-car-service
eureka:
instance:
hostname: localhost
prefer-ip-address: true
instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
client:
service-url:
defaultZone: http://localhost:8761/eureka
测试结果
启动服务提供者和服务消费者。浏览器访问http://localhost:9091/customerRent
浏览器显示租车成功
停止服务端,重新刷新浏览器,Hystrix的备选方案生效,重新启动服务端,再次刷新浏览器。服务恢复!
Hystrix的常用配置hystrix: #hystrix 的全局控制
command:
default: #default 是全局控制,也可以换成单个方法控制,把 default 换成方法名即可
circuitBreaker:
enabled: true #开启断路器
requestVolumeThreshold: 3 #失败次数(阀值)
sleepWindowInMilliseconds: 20000 #窗口时间
errorThresholdPercentage: 60 #失败率
fallback:
isolation:
semaphore:
maxConcurrentRequests: 1000 #信号量隔离级别最大并发数
execution:
isolation:
Strategy: thread #隔离方式thread线程隔离集合和SEMAPHORE信号量隔离级别
thread:
timeoutInMilliseconds: 3000 #调用超时时长
暑期编程PK赛
得CSDN机械键盘等精美礼品!


