服务熔断

服务熔断是由Martin Fowler提出的服务保护机制,Hystrix的服务熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务出错不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。当检测到该节点微服务调用响应正常后,恢复调用链路。
在Spring Cloud框架里,熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,默认的是5秒内20次调用失败,超过50%的失败率,就会启动熔断机制。熔断机制的注解是@HystrixCommand。

服务熔断案例

修改Service

package com.gcl.springcloud.service;

import cn.hutool.core.util.IdUtil;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class HystrixService {

    public String paymentInfo_ok(Integer id){
        return "线程池: "+ Thread.currentThread().getName() + " paymentInfo_ok " + id;
    }

    @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler"/*指定善后方法名*/,commandProperties = {
            @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="3000")
    })
    public String paymentInfo_timout(Integer id){
        try{
            TimeUnit.SECONDS.sleep( 5 );
        }catch (Exception e){
            e.printStackTrace();
        }
        return "线程池: "+ Thread.currentThread().getName() + " paymentInfo_timout " + id;
    }

    public String paymentInfo_TimeOutHandler(Integer id){
        return "业务繁忙,请稍后再试";
    }

    //=====服务熔断
    @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"),// 失败率达到多少后跳闸
    })
    public String paymentCircuitBreaker(Integer id) {
        if(id < 0) {
            throw new RuntimeException("******id 不能负数");
        }
        String serialNumber = IdUtil.simpleUUID();

        return Thread.currentThread().getName()+"\t"+"调用成功,流水号: " + serialNumber;
    }
    public String paymentCircuitBreaker_fallback(Integer id) {
        return "id 不能负数,请稍后再试,/(ㄒoㄒ)/~~   id: " +id;
    }
    
}

修改Controller

package com.gcl.springcloud.controller;

import com.gcl.springcloud.service.HystrixService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@Slf4j
public class HystrixController {

    @Resource
    private HystrixService hystrixService;

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


    @GetMapping("/payment/hystrix/ok/{id}")
    public String ok(@PathVariable("id") Integer id ){
        return hystrixService.paymentInfo_ok(id);
    }

    @GetMapping("/payment/hystrix/timout/{id}")
    public String timout(@PathVariable("id") Integer id ){
        return hystrixService.paymentInfo_timout(id);
    }

    //====服务熔断
    @GetMapping("/payment/circuit/{id}")
    public String paymentCircuitBreaker(@PathVariable("id") Integer id)
    {
        String result = hystrixService.paymentCircuitBreaker(id);
        log.info("****result: "+result);
        return result;
    }

}

运行

我们需要启动微服务,其次我们这个服务的接口在输入负数时会报错,我们输入正数就会返回正常的结果.
在这里插入图片描述
在这里插入图片描述
其次我们已经设置了Hystrix的服务熔断,我们设置了10秒内收到了10个请求时如果失败率大于60%时我们就会开启服务熔断(服务降级),开启后如果后续的请求成功率变的高的话,熔断就会被关闭,我们先用大量负数去请求,当开启熔断后,输入正数也会返回降级后的信息.
在这里插入图片描述
在这里插入图片描述

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐