欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

hystrix的服务降级

程序员文章站 2024-03-20 22:19:16
...

hystrix的服务降级

前言

通常情况下,一次远程调用对应着一个线程/进程。如果响应太慢,这个线程/进程就得不到释放。而线程/进程对应着系统资源,如果得不到释放的线程/进程就会越积越多,资源就会被耗尽,最终导致服务不可用!hystrix就是解决这类问题的工具类库。

服务降级

用自己的话来说,就是当某个服务不可用的时候,有一个兜底的程序(fallback)进行数据返回,这样服务器的压力会减轻很多,因为当接口运行超时、宕机的时候,接口就会一直在请求或者重新连接,当数据量大的时候,服务器肯定会崩掉的,从而影响到其他的服务。

具体用法

pom

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

修改主启动类

@SpringBootApplication
@EnableFeignClients
@EnableHystrix
public class SpringBootAppFeignHystrix80 {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootAppFeignHystrix80.class,args);
    }
}

@EnableHystrix就是启动hystrix,一贯的springboot启动套路

服务降级小案例

    @GetMapping("/consumer/payment/hystrix/timeout/{id}")
    @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutFallback", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500")
    })
    public String paymentInfo_TimeOut(@PathVariable("id") Integer id){
//        int  a =  1/0 ;
        String result = paymentHystrixService.paymentInfo_TimeOut(id);
        log.info("*******result:"+result);
        return result;
    }


    public String paymentInfo_TimeOutFallback(@PathVariable("id") Integer id){
        return "我是消费者80,对方支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,(┬_┬)";
    }

代码解读:@HystrixCommand注解,作用方法体上,其属性fallbackMethod就是用来定义“兜底”方法的。
@HystrixProperty(name = “execution.isolation.thread.timeoutInMilliseconds”,value = “1500”) 意思是如果方法在1.5秒没有返回,就执行兜底方法,不在等待程序执行。

思考问题

如果按照上面的服务降级案例来处理相关问题,会发现我们的代码和兜底程序的耦合度太高,不利于后期扩展,所以这个时候我们需要思考,有没有一种全局的兜底程序?

答案当然是有的!

我可以在controller上面加上@DefaultProperties注解,属性defaultFallback中指定就是默认的兜底方法

案例如下

@RestController
@Slf4j
@DefaultProperties(defaultFallback = "defaultFallback")
public class OrderHystrixController {
  
    @GetMapping("/consumer/payment/hystrix/ok/{id}")
    @HystrixCommand
    public String paymentInfo_OK(@PathVariable("id") Integer id){
        int a = 1/0;
        String result = paymentHystrixService.paymentInfo_OK(id);
        log.info("*******result:"+result);
        return result;
    }
  
  	public String defaultFallback (Throwable throwable) {
        log.error("进入兜底方法,错误日志:",throwable);
        return "***** defaultFallback ****";
    }
}

小细节:我们可以在fallback方法,后面加上throwable,这样我们就可以捕获导致fallback的原因!

feign使用hystrix

application.xml添加fegin.hystrix.enabled:true

@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT",fallback =PaymentHystrixFallBackService.class )
public interface PaymentHystrixService {

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

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

}



@Component
public class PaymentHystrixFallBackService implements PaymentHystrixService  {

    @Override
    public String paymentInfo_OK(Integer id) {
        return "PaymentHystrixFallBackService  paymentInfo_OK ";
    }

    @Override
    public String paymentInfo_TimeOut(Integer id) {
        return "PaymentHystrixFallBackService  paymentInfo_TimeOut ";
    }
}

由代码可知,只需使用@FeignClient注解的fallback属性,就可以指定名称为feign客户端添加兜底程序