SpringCloud feign微服务调用之间的异常处理方式

 更新时间:2021年06月24日 09:11:58   作者:zf12178  
这篇文章主要介绍了SpringCloud feign微服务调用之间的异常处理方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

如何优雅地处理微服务间调用的异常

现在微服务架构盛行,其中spring cloud方案就很具有代表。

那么在微服务之间进行调用,如果被调用的服务挂了,调用方如何感知呢?

一、加上hystrix熔断

在定义feignClient的地方指定熔断,如下图

熔断

当被调用服务不可用或者被调用方发生错误的时候,会触发熔断,但是,如果被调用方抛出异常,调用方怎么知道究竟是出了什么问题呢?

那,这就出现了

二、feign全局异常处理

我们不得不提到feign提供的一个接口叫做ErrorDecoder, 是用来处理feign异常的,有一个方法需要实现 public Exception decode(String s, Response response)

如下图:

在这里插入图片描述

这样就会替换它默认的feign异常处理,这样就可以捕捉全局的异常了,但是又带来一个新的问题,如果使用这个ErrorDecoder,得关闭熔断,否者这里抛出的FeignBadRequestException异常又会被hystrix吞掉,那,有没有更好的办法呢?

在被调用的controller方法里面捕捉全局异常,发生错误的时候,把异常保存一个对象里面,然后用该对象进行服务间的通信,调用方收到结果再检查是否包含错误,这个方式确实可以解决,但,这肯定不是个好办法;那么有没有更好的办法呢?跳出ErrorDecoder后,会经过在AbstractCommand里面的一个executeCommandAndObserve方法里面有个function叫做 handleFallback

由此可知,当抛出的异常是HystrixBadRequestException时,直接抛出异常,不再经过fallback,那么我们的解决办法就有了,那就是调整FeignBadRequestException 的继承对象,如图

调整异常继承方案

现在,就实现了服务端不可用和服务端报错的异常分离,但是可能,有的同学已经注意到了,FeignClientErrorDecoder这个异常处理类里面是是针对状态为SERVICE_UNAVAILABLE的进行了特别处理,为社么要这样?这是因为与被调用方约定当状态码为 SERVICE_UNAVAILABLE 的时候视为被调用方主动抛出的异常

需要注意的地方

我们的被调用方除了提供微服务之间调用,很可能也提供了面向前端的接口,为了封装我们程序内部的异常,通常我们会定义个全局异常捕捉类,即使报错了,我们也提供一个友好的交互方式,比如下面这样

第一处我们除了系统内部抛出的异常,第二处处理其它异常,也就是说,不管抛出什么错,该服务都会返回一个状态值为200的信息出去,那么问题来了,我们微服务间的调用也会被处理成200,从而导致feign会以为服务是正常的,正常返回结果了,没有报错,那怎么办?

三、针对内部调用的特殊处理

当然,你可能想到了,我们可以在提供给内部使用的接口进行异常转换,然后让全局异常处理处不进行这样的处理,但是,每个内部接口都要进行全局异常捕捉,然后转换,这,明显不是最好的做法

四、通过注解标记为接口为内部调用接口

先定义一个注解,直接上图

注解

我们定义该注解为方法和类上都可以使用,然后再定义处理程序

在这里插入图片描述

处理程序要做一件事情,就是在程序方法异常的时候,将http状态码设置为我们约定的SERVICE_UNAVAILABLE,然后看下怎么使用

标记异常

这样我们把该方法标记为了供内部使用的接口,当然,同样也可以将注解放在类上,这样就可以把该类的全部方法标记为内部调用。

至此,我们现在调用其它服务的方法,就可以调用本地的一样了,当然,如果你想在调用其它服务的方法报错后想继续执行其它逻辑,同样也可以,直接catch FeignBadRequestException 这个异常就可以了

微服务间调用异常改参

两个微服务之间通过feign调用时,后台抛出异常:

feign.RetryableException: Read timed out executing POST

解决方法:

在你的yml文件中添加

ribbon:  
  ReadTimeout: 60000  
  ConnectTimeout: 60000

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 关于SpringSecurity简介以及和Shiro的区别

    关于SpringSecurity简介以及和Shiro的区别

    这篇文章主要介绍了关于SpringSecurity简介以及和Shiro的区别,在Java应用安全领域,Spring Security会成为被首先推崇的解决方案,就像我们看到服务器就会联想到Linux一样顺理成章,需要的朋友可以参考下
    2023-07-07
  • Java之字节码以及优势案例讲解

    Java之字节码以及优势案例讲解

    这篇文章主要介绍了Java之字节码以及优势案例讲解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • SpringBoot中Bean生命周期自定义初始化和销毁方法详解

    SpringBoot中Bean生命周期自定义初始化和销毁方法详解

    这篇文章给大家详细介绍了SpringBoot中Bean生命周期自定义初始化和销毁方法,文中通过代码示例讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-01-01
  • Java ConcurrentHashMap用法案例详解

    Java ConcurrentHashMap用法案例详解

    这篇文章主要介绍了Java ConcurrentHashMap用法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • java对象与json对象之间互相转换实现方法示例

    java对象与json对象之间互相转换实现方法示例

    这篇文章主要介绍了java对象与json对象之间互相转换实现方法,结合实例形式分析了java对象与json对象相互转换实现步骤与相关操作技巧,需要的朋友可以参考下
    2017-10-10
  • ElasticSearch6.2.3+head插件安装的方法步骤

    ElasticSearch6.2.3+head插件安装的方法步骤

    这篇文章主要介绍了ElasticSearch6.2.3+head插件安装的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-02-02
  • 带你了解Java数据结构和算法之无权无向图

    带你了解Java数据结构和算法之无权无向图

    这篇文章主要为大家介绍了Java数据结构和算法之无权无向图 ,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • Mybatis实现动态增删改查功能的示例代码

    Mybatis实现动态增删改查功能的示例代码

    这篇文章主要介绍了Mybatis实现动态增删改查功能的示例代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • Java正则判断日期格式是否正确的方法示例

    Java正则判断日期格式是否正确的方法示例

    这篇文章主要介绍了Java正则判断日期格式是否正确的方法,结合实例形式分析了Java针对日期字符串正则判断的相关操作技巧,需要的朋友可以参考下
    2017-03-03
  • IDEA运行导入的javaweb项目tomcat正常,但是运行失败404问题

    IDEA运行导入的javaweb项目tomcat正常,但是运行失败404问题

    这篇文章主要介绍了IDEA运行导入的javaweb项目tomcat正常但是运行失败404问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07

最新评论