Hystrix 服务降级与熔断

基本概念

服务雪崩:

多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C有调用其他的微服务,这就是所谓的”扇出”,如扇出的链路上某个微服务的调用响应式过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统雪崩,所谓的”雪崩效应”

Hystrix:

Hystrix是一个用于分布式系统的延迟和容错的开源库。在分布式系统里,许多依赖不可避免的调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整个服务失败,避免级联故障,以提高分布式系统的弹性。

断路器:

“断路器”本身是一种开关装置,当某个服务单元发生故障监控(类似熔断保险丝),向调用方法返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方法无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延。乃至雪崩。

服务熔断:

熔断机制是应对雪崩效应的一种微服务链路保护机制,

当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回”错误”的响应信息。当检测到该节点微服务响应正常后恢复调用链路,在SpringCloud框架机制通过Hystrix实现,Hystrix会监控微服务见调用的状况,当失败的调用到一个阈值,缺省是5秒内20次调用失败就会启动熔断机制,熔断机制的注解是@HystrixCommand

服务降级:

当某个服务出现异常之后,服务器将不再被调用,此时服务端可以自己准备一个本地的fallback回调,返回一个缺省值。

Hystrix与Feign集成,并实现降级与熔断:

准备一个准备一个服务提供端8001

  1. yml配置
server.port=8001
spring.application.name=cloud-provider-hystrix-payment

#eureka实例名称
eureka.instance.hostname=localhost
#表示向注册中心注册自己
eureka.client.register-with-eureka=true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
eureka.client.fetch-registry=false
#设置与Eureka server交互的地址查询服务和注册服务都需要依赖这个地址
eureka.client.service-url.defaultZone=http://eureka7001.com:7001/eureka/

2.创建测试使用的service与controller

@Service
public class PaymentService {

    /**
     * 正常访问
     *
     * @param id
     * @return
     */
    public String paymentInfo_OK(Integer id) {
        return "线程池:" + Thread.currentThread().getName() + " paymentInfo_OK:" + id;
    }

    /**
     * @param id
     * @return
     */
     //执行此方法时当先线程将会休眠三秒,三秒之后才会返回结果
    public String paymentInfo_TimeOut(Integer id) {
        int timeNumber = 3;
        try {
            TimeUnit.SECONDS.sleep(timeNumber);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "线程池:" + Thread.currentThread().getName() + " paymentInfo_TimeOut:" + id + "  耗时:" + timeNumber + "秒";
    }

  1. 创建controller

@RestController
@RequestMapping("/payment")
@Slf4j
public class PaymentController {

    @Autowired
    private PaymentService paymentService;

    @Value("${server.port}")
    private String serverPort;

    @GetMapping("/hystrix/ok/{id}")
    public String paymentInfo_OK(@PathVariable("id") Integer id){
        //int a = 10/0;
        String s = paymentService.paymentInfo_OK(id);
        log.info("result********"+s);
        return s;
    }

    @GetMapping("/hystrix/timeout/{id}")
    public String paymentInfo_Timeout(@PathVariable("id") Integer id){
        String s = paymentService.paymentInfo_TimeOut(id);
        log.info("result********"+s);
        return s;
    }
}

准备一个消费者端

1.在配置文件中添加配置

server.port=80
spring.application.name=cloud-consumer-hystrix-order

#表示向注册中心注册自己
eureka.client.register-with-eureka=true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
eureka.client.fetch-registry=false

#设置与Eureka server交互的地址查询服务和注册服务都需要依赖这个地址
eureka.client.service-url.defaultZone=http://eureka7001.com:7001/eureka/
#设置别名
#eureka.instance.instance-id=payment8001
#显示ip地址
#eureka.instance.prefer-ip-address=true

#开启feign对hystrix的支持
feign.hystrix.enabled=true
#feign连接时间
feign.client.config.default.connect-timeout=3000
#feign读取时间
feign.client.config.default.readTimeout=3000

2.在启动类中添加注解

@SpringBootApplication
//启用服务注册发现功能
@EnableEurekaClient
//启用Feign
@EnableFeignClients
//启动Hystrix
@EnableHystrix
//开启熔断器
@EnableCircuitBreaker
public class OrderHystrixMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderHystrixMain80.class,args);
    }
}

3.面向服务提供端8001提供的api创建接口,同时创建一个实现类。当服务提供端8001调用出现异常、超时、宕机等问题时,将会执行fallback备用方法

//value :在Eureka服务注册中心中注册的服务名,fallback :PaymentHystrixServiceApi 的实现类
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT",fallback = PaymentFallbackService.class)
@Component
public interface PaymentHystrixServiceApi {

    @GetMapping("/payment/hystrix/timeout/{id}")
    public String paymentInfo_Timeout(@PathVariable("id") Integer id);

    @GetMapping("/payment/hystrix/ok/{id}")
    public String paymentInfo_OK(@PathVariable("id") Integer id);
}

4.fallback对PaymentHystrixServiceApi 进行实现

@Component
public class PaymentFallbackService implements PaymentHystrixServiceApi {

    @Override
    public String paymentInfo_Timeout(Integer id) {
        return "PaymentFallbackService for back paymentInfo_Timeout, o(╥﹏╥)o";
    }

    @Override
    public String paymentInfo_OK(Integer id) {
        return "PaymentFallbackService for back paymentInfo_OK, o(╥﹏╥)o";
    }
}

5.controller中对服务进行调用


@RestController
@RequestMapping("/consumer")
public class OrderHystrixController {

    @Autowired
    private PaymentHystrixServiceApi paymentHystrixServiceApi;


    @GetMapping(value = "/payment/hystrix/timeout/{id}",produces = MediaType.APPLICATION_JSON_VALUE)
    public String paymentInfo_Timeout(@PathVariable("id") Integer id){
        String s = paymentHystrixServiceApi.paymentInfo_Timeout(id);
        System.out.println("timeout:"+s);
        return s;
    }

    @GetMapping(value = "/payment/hystrix/ok/{id}",produces = MediaType.APPLICATION_JSON_VALUE)
    public String paymentInfo_OK(@PathVariable("id") Integer id){
        String s = paymentHystrixServiceApi.paymentInfo_OK(id);
        System.out.println("ok:"+s);
        return s;
    }
 }

6.先启动Eureka服务注册中心,在启动服务提供端与消费者端,然后进行测试

  • 当服务提供端线程睡眠时间设置没有超过feign的读取时间时,服务调用成功
    在这里插入图片描述
  • 当服务提供端线程睡眠时间设置超过feign的读取时间时,服务调用成功失败,调用这个服务的fallback方法
    在这里插入图片描述
  1. 当服务多次调用失败时,将会进入熔断打开的状态,停止对服务提供端的调用,直接对服务进行降级,以防止服务的雪崩,在这里就不演示了,但是可以通过下面的配置进行熔断的属性设置
@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")//失败率达到多少后跳闸
    })

8.在Hystrix中有一个配置类HystrixCommandProperties,上面有更多的配置选择与描述,可自行翻阅

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值