springcloud 系列之 feign 熔断 和异常抛出的问题

场景:

在服务间调用的时候 , 当我需要抛出异常的时候希望能将异常在服务间抛出 。

当我需要熔断的时候,还是走feign 的熔断

解决方式

方式一 :

配置增加 feign.hystrix.enabled=false 全局关闭feign 的熔断

在添加如下配置 在这里使用了 ErrorDecoder  这个是feign 的 一个统一的异常处理

@Slf4j
@Configuration
public class InternalApiErrorDecoder implements ErrorDecoder {

    @Override
    public Exception decode(String methodKey, Response response) {
        String msg = null;
        try {
            String json = Util.toString(response.body().asReader());
            JSONObject jsonObject = JSON.parseObject(json);
            msg = jsonObject.getString("message");
            if (msg.contains(":")) {
                String resultCode = msg.split(":")[0];
                String resultMsg = msg.split(":")[1];
                return new InternalApiException(resultCode, resultMsg);
            }
        } catch (IOException e) {
            log.info(e.getMessage());
        }
        // 对于服务间调用的 非  InternalApiException 异常 ,
        // 还是需要使用降级的方式 , 那么抛出 Exception 异常 。 则会自动降级
        // , 如果有必要全部捕获 那么 这里可以改为 InternalApiException
        // return new InternalApiException("000000", msg);
        return new Exception(msg);
    }
}

这个时候 就能直接抛出异常了在 调用方能够获取这个错误

方案二 :

在网上查阅信息后发现  HystrixBadRequestException 这个异常的时候 feign  是不会熔断的

所以 我们在自定义的服务间的异常类使用  如下代码

public class InternalApiException extends HystrixBadRequestException {
    // HystrixBadRequestException 异常 feign 去处理的时候是不会使用熔断的 所以需要继承这个类
    private static final long serialVersionUID = -1549118434059351846L;

    private String resultCode;
    private String resultMsg;

    public InternalApiException(String resultCode, String resultMsg) {
        super(resultCode+":"+resultMsg);
        this.resultCode = resultCode;
        this.resultMsg = resultMsg;
    }

}

然后在使用 ErrorDecoder 这个时候当我在 auth 服务抛出这个异常 ,我在 user服务中获取这个异常 , 当连接超时 或者抛出其他类型异常的话 , user 服务则会使用熔断的方式

@Slf4j
@Configuration
public class InternalApiErrorDecoder implements ErrorDecoder {

    @Override
    public Exception decode(String methodKey, Response response) {
        String msg = null;
        try {
            String json = Util.toString(response.body().asReader());
            JSONObject jsonObject = JSON.parseObject(json);
            msg = jsonObject.getString("message");
            if (msg.contains(":")) {
                String resultCode = msg.split(":")[0];
                String resultMsg = msg.split(":")[1];
                return new InternalApiException(resultCode, resultMsg);
            }
        } catch (IOException e) {
            log.info(e.getMessage());
        }
        // 对于服务间调用的 非  InternalApiException 异常 ,
        // 还是需要使用降级的方式 , 那么抛出 Exception 异常 。 则会自动降级
        // , 如果有必要全部捕获 那么 这里可以改为 InternalApiException
        // return new InternalApiException("000000", msg);
        return new Exception(msg);
    }
}

推荐使用方案二 

代码地址 github   https://github.com/1042545965/conlon-cloud/tree/master/conlon-cloud-api

感谢一下二位的博客

https://blog.csdn.net/Coder_Joker/article/details/81811567

http://blog.didispace.com/rencong-1/

你可能感兴趣的:(springcloud,JAVA,springboot)