springCloud:Hystirx 服务熔断,服务降级

前言:

 在复杂分布式架构体系中,应用程序往往会有数十个依赖关系,而每个依赖关系在某些时候将不可避免的失败,造成当前服务不可用,而在高并发的环境下,当服务挂掉后,服务消费者依然在请求服务,这就会走造成当前服务的瘫痪,即便被重试唤醒,但面临堆积起来的大量服务请求,服务提供者会再次挂掉,这就是服务雪崩

服务雪崩

 通俗的说:当服务间的关系非常复杂,耦合高,那么当一个服务挂掉了,那么跟他存在依赖关系的服务也就相应的会被阻塞,这就是雪崩效应,

 解决:服务熔断,服务降级  

服务熔断和降级区别 

例子:

 总结服务熔断就是当一个微服务的某个程序模块出现了问题,导致当前服务挂掉,触发熔断机制,给这个程序模块一个(备选方案),用来顶替坏掉的方法,让当前服务可以正常运行

   触发原因:服务的某个模块(如:方法)异常/挂掉/超时

   解决:启用备份方法顶替原有方法

   目的:让服务正常运行,一般是给用户可视化的相关错误信息而不是一堆异常信息,提高系统的容错性的同时增强用户的体验性

   服务降级:某给服务并发量过高,cpu承受不了,关闭部分不重要服务,节省资源占用

   触发原因:开发人员主动关闭某服务

   解决方案:执行备选服务,给客户端提醒信息,当前服务不可用

   目的:节省cpu资源,交给并发量高的服务去使用

 注意:服务熔断是在服务端(服务提供者),服务降级是客户端开发(服务消费者),两者开发位置不同

    服务熔断是被动的,降级是主动的

Hystrix是什么

是一个对微服务架构中的异常进行处理一个中间件,如服务雪崩;提高了分布是系统的容错性,不会因为某些服务模块的挂掉而影响整个系统的正常运行

Hystrix作用

  • 基于命令模式的请求:解耦了请求者和接受者,使得发送出去的命令可以排队、异步执行。
  • 资源隔离:用ConcurrentHashMap绑定commandKey和线程池,当某个功能运行不稳定或有问题时,服务的其他部分不受影响。服务恢复比较快。
  • 熔断和服务降级:用ConcurrentHashMap绑定commandKey和HystrixCircuitBreaker类(断路器类),统计每次请求的结果并记录,根据结果判断是否开启断路器,自定义异常返回结果实现熔断降级。

一,服务熔断配置

@EnableCircuitBreaker  开启断路器,属于hystrix的包

 1.导入依赖

        <!--Hystrix-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>

2.服务提供者controller层方法处加服务熔断相关注解,本质给方法加备选方案(当服务挂了,备选方案被调用)

@HystrixCommand(fallbackMethod = "备选方案方法名")

//提供Restful服务
@RestController
public class DeptController {

    @Autowired
    private DeptService deptService;


    @GetMapping("/dept/get/{id}")
    @HystrixCommand(fallbackMethod = "hystrixGet")
    public Dept get(@PathVariable("id") Long id){
        Dept dept = deptService.queryById(id);

        if(dept == null){
            throw new RuntimeException("id=>"+id+"不存在该用户,或者信息无法找到~");
        }

        return dept;
    }


    //熔断版的(本质,备选方法)
    public Dept hystrixGet(@PathVariable("id") Long id) {
            return new Dept()
                    .setDeptno(id)
                    .setDname("id=>"+id+"不存在该用户,或者信息无法找到~")
                    .setDb_source("no this datasource in MySQL");

    }


}
View Code

3.主启动类开启断路器

@EnableCircuitBreaker //开启断路器,属于hystrix的包

@SpringBootApplication
@EnableDiscoveryClient //服务发现,企业级协同开发
@EnableEurekaClient  //开启eureka客户端,在服务启动后自动注册到指定的EurekaServer中
@EnableCircuitBreaker //开启断路器,属于hystrix的包
public class DeptProvider_8001 {
    public static void main(String[] args) {
        SpringApplication.run(DeptProvider_8001.class,args);
    }
}
View Code

二,服务降级配置(feign的包集成了hystrix)

在api+服务消费者端配置

1.api端(共有端)配置,

作用:服务各服务的一个端,通常引封装成pom方式各端使用

(1)服务降级后触发的类

//服务降级
@Component
public class DeptClientServiceFallBackFactory implements FallbackFactory {
    @Override
    public DeptClientService create(Throwable throwable) {
        return new DeptClientService() {
            @Override
            public Dept queryById(Long id) {
                return new Dept()
                        .setDeptno(id)
                        .setDname("id=>"+id+"没有对应的信息,客户端提供了降级的信息,这个服务已经被关闭")
                        .setDb_source("没有数据~");
            }

            @Override
            public List<Dept> queryAll() {
                return null;
            }

            @Override
            public Boolean addDept(String dname) {
                return null;
            }
        };
    }
}
View Code

(2)绑定服务降级的类

//注册到spring容器里
@Component
//绑定服务id,fallback服务降级(绑定的类)
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT",fallbackFactory = DeptClientServiceFallBackFactory.class)
public interface DeptClientService {

     @GetMapping("/dept/get/{id}")
     Dept queryById(@PathVariable("id") Long id);

     @GetMapping("/dept/list")
     List<Dept> queryAll();

     @PostMapping("/dept/add")
     Boolean addDept(String dname);

}
View Code

2.服务消费者端配置‘(yaml)

#开启降级,feign,Hystrix共用,默认false
feign:
  hystrix:
    enabled: true
原文地址:https://www.cnblogs.com/CL-King/p/14339213.html