Hystrix 请求命令 & 异常处理

1.请求命令

请求命令就是以继承类的方式来代替前面的注解方式。

接着上文,首先定义一个helloCommand:

public class HelloCommand extends HystrixCommand<String> {

    RestTemplate restTemplate;

    public HelloCommand(Setter setter,RestTemplate restTemplate) {
        super(setter);
        this.restTemplate = restTemplate;
    }

    /**
     * String类型为上面定义的泛型
     * @return
     * @throws Exception
     */
    @Override
    protected String run() throws Exception {
        return restTemplate.getForObject("http://provider/hello",String.class);
    }
}

调用方法:

@GetMapping("/hello2")
    public void hello2(){
        HelloCommand helloCommand = new HelloCommand(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("hellojava")), restTemplate);
        /** 两种调用方法
         *  一、直接调用【同步】
         *  【注意:HelloCommand new出来之后只能调用一次,两种方法只执行一次】
         * */
        String execute = helloCommand.execute();
        System.out.println(execute);
        HelloCommand helloCommand2 = new HelloCommand(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("hellojava")), restTemplate);

        /** 二、先入队,后执行 【异步】*/
        String s = null;
        try {
            Future<String> queue = helloCommand2.queue();
            s = queue.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        System.out.println(s);

    }

 启动eureka server和provider以及hystrix ,访问http://localhost:3000/hello2 在控制台查看结果。

 1.1通过注解实现请求异步调用

@HystrixCommand(fallbackMethod = "error")
    public Future<String> hello2(){
        return new AsyncResult<String>(){

            @Override
            public String invoke() {
                return restTemplate.getForObject("http://provider/hello",String.class);
            }
        };
    }
@GetMapping("/hello3")
    public void hello3(){
        Future<String> stringFuture = helloService.hello2();
        String s = null;
        try {
            s = stringFuture.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        System.out.println(s);

    }

 重启hystrix项目,访问:http://localhost:3000/hello3 如下:

1.2通过继承方式使用Hystrix, 重写继承类的 getFallback 方法实现服务容错/降级。

public class HelloCommand extends HystrixCommand<String> {

    RestTemplate restTemplate;

    public HelloCommand(Setter setter,RestTemplate restTemplate) {
        super(setter);
        this.restTemplate = restTemplate;
    }

    
    @Override
    protected String run() throws Exception {
        return restTemplate.getForObject("http://provider/hello",String.class);
    }

    /**
     * 请求失败的回调
     * @return
     */
    @Override
    protected String getFallback(){
        return "error-extends";
    }

}

重启hystrix项目 访问hello2接口。(启动2个provider,都注册到eureka,,再关闭一个,刷新才能看到效果,与一开始的注解式方式相似)

2.异常处理

 就是当发起服务时,如果不是provider的原因导致请求调用失败,而是 consumer 中本身代码有问题导致的请求失败,即 consumer中抛出了异常,这个时候,也会自动进行服务降级,只不过这个时候降级,我们还需要知道到底哪里出错了。

如下例实例代码,如果hello方法执行时抛出异常,那么一样会进行服务降级,进入到 error 方法中,然后获取到异常的详细及信息。

@Service
public class HelloService {

    @Autowired
    RestTemplate restTemplate;

    /**
     * 在这个方法中,将发起一个远程调用,去调用provider中提供的 /hello接口
     * 但是调用这个方法可能会失败,
     *
     * 所以在方法上面添加 @HystrixCommand ,配置fallbackMethod 属性,这个属性表示该方法调用失败时的临时替代方法
     * 【专业术语:服务降级】 */
    @HystrixCommand(fallbackMethod = "error")//如果希望直接抛出异常,不做服务降级 。则再加上ignoreExceptions配置(fallbackMethod = "error",ignoreExceptions = ArithmeticException.class)
    public String hello(){
        int i = 1 / 0;
        return restTemplate.getForObject("http://provider/hello",String.class);
    }


    /**
     * 这个方法名要和 fallbackMethod一致
     * 方法返回值也要一致 【比如这里都是String类型,error也要一致】
     * 此处 调用 备案方案 ,比如数据库崩了,就要去查缓存
     *
     * *    **下面也可以继续写HystrixCommand调用error2 ,然后error2再去调用其它的方法,方法一样,依次往下,这就是【服务降级】
     * *    **越往下,数据的获取能力越来越容易,准确性可能降低,但不会让系统挂掉。
     * *    ** 这就是Hystrix 的作用: 1. 降级  2. 容错。  避免雪崩  。
     *
     * @return
     */
    //@HystrixCommand(fallbackMethod = "error2")
    public String error(Throwable t){
        return "error"+t.getMessage();
    }
}

这是注解的方式,也可以通过继承的方式:

public class HelloCommand extends HystrixCommand<String> {

    RestTemplate restTemplate;

    public HelloCommand(Setter setter,RestTemplate restTemplate) {
        super(setter);
        this.restTemplate = restTemplate;
    }

    /**
     * String类型为上面定义的泛型
     * @return
     * @throws Exception
     */
    @Override
    protected String run() throws Exception {
        int i = 1 / 0;//测试异常
        return restTemplate.getForObject("http://provider/hello",String.class);
    }

    /**
     * 请求失败的回调
     * @return
     */
    @Override
    protected String getFallback(){
        return "error-extends"+getFailedExecutionException().getMessage();
    }

}

如果是通过继承的方式来做 Hystrix ,在getFallback 方法中,我们可以通过 getExecutionException 方法来获取执行的异常信息。

另一种可能性。如果抛出异常了,我们希望异常直接抛出,不要服务降级,那么只需要配置忽略某一个异常即可:

@Override
    protected String hello() {
        int i = 1 / 0;//测试异常
        return restTemplate.getForObject("http://provider/hello",String.class);
    }

代码示例地址:https://github.com/astronger/springcloud-simple-samples 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李多肉同学

长得好看的人一般都喜欢发红包

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值