Hystrix--熔斷

吃茄子的貓發表於2020-10-02

服務熔斷是指當服務訪問頻繁被拒絕後會呼叫服務降級的fallbackMethod方法拒絕訪問, 當過一段時間後會進入半開狀態先允許一部分請求進行訪問如果可以則調整為全開狀態
在這裡插入圖片描述
在這裡插入圖片描述
1.主啟動

@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class PaymentHystrixMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentHystrixMain8001.class,args);
    }
    /*
     * 此配置是為了服務監控而配置,與服務容錯本身無關,spring cloud升級後的坑
     * servletRegistrationBean因為springboot的預設路徑不是"/.hystrix.stream"
     * 只要在自己的專案裡配置上下面的servlet就可以了
     * */
    @Bean
    public ServletRegistrationBean getsServlet(){
        HystrixMetricsStreamServlet streamServlet=new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean=new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }
}

二、service層

@Service
public class PaymentService {
    public String paymentInfo_OK(Integer id){
        return "執行緒池: "+Thread.currentThread().getName()+" paymentInfo_OK,id: "+id+"\t"+"O(∩_∩)O哈哈";
    }
    @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")
    })
    public String paymentInfo_TimeOut(Integer id){
        int timenumbe=3000;
//        int age=10/0;
        try {
            TimeUnit.MILLISECONDS.sleep(timenumbe);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "執行緒池: "+Thread.currentThread().getName()+" paymentInfo_TimeOut,id: "+id+"\t"+"O(∩_∩)O哈哈"+"耗時(毫秒 ): "+timenumbe;
    }

    public String paymentInfo_TimeOutHandler(Integer id){
        return "執行緒池: "+Thread.currentThread().getName()+" 8001系統忙,請稍後再試,id: "+id+"\t"+"┭┮﹏┭┮";
    }
    //服務熔斷
    @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(@PathVariable("id") Integer id){
        if (id<0){
            throw new RuntimeException("**********id 不能負數");
        }
        String serialNumber=IdUtil.simpleUUID();//等價於UUID.randomUUID().toString()
        return Thread.currentThread().getName()+"\t"+"呼叫成功,流水號: "+serialNumber;
    }
    public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id){
        return "id 不能負數,請稍後再試,┭┮﹏┭┮ id: "+id;
    }
}

三、controller

@RestController
@Slf4j
public class PaymentController {
    @Resource
    private PaymentService paymentService;
    @Value("${server.port}")
    private String serPort;
    @GetMapping("/payment/hystrix/ok/{id}")
    public String paymentInfo_OK(@PathVariable("id") Integer id){
        String result=paymentService.paymentInfo_OK(id);
        log.info("******result: "+result);
        return result;
    }
    @GetMapping("/payment/hystrix/timeout/{id}")
    public String paymentInfo_timeOut(@PathVariable("id") Integer id){
        String result=paymentService.paymentInfo_TimeOut(id);
        log.info("******result: "+result);
        return result;
    }
    //===服務熔斷
    @GetMapping("/payment/circuit/{id}")
    public String paymentCircuitBreaker(@PathVariable("id")Integer id){
        String result=paymentService.paymentCircuitBreaker(id);
        log.info("*******result: "+result);
        return result;
    }
}

相關文章