Feign的不恰当的fallback

Feign的坑不少,特别与Hystrix集成之后。

在微服务引入Feign后,上线不久后便发现,对于一个简单的查询类调用,在下游返回正常的"404-资源不存在"这种业务异常时,Feign也做了fallback,最终导致circuit break,引发平台告警。

REST接口的设计

为了解释这个问题,首先还是要从REST接口开始谈起。

REST的一个缺点(也有人认为是优势),它只是一种依赖于HTTP的"风格",而没有明确的"规范",所以客户端和服务端之间,要自行达成某种"约定"。

例如返回码,就要硬往HTTP STATUS上靠。

关于返回码,公认的"最佳实践"大概是这样的:

  1. 如果业务处理成功,http status返回200、204等。如果有内容,BODY中直接返回内容(对象或数组都可以),不再有RPC时代的code/message这样的状态描述。如果没有内容,BODY直接空白,No News Is Good News。
  2. 如果业务处理失败,业务逻辑导致的,则http status返回4XX,BODY中返回报错信息,报错信息的统一格式大概是这样的:
{
"status": 409, // 冗余字段,把http status再重复一遍
"code": 888, // 自定义的错误码
"message": "foobar" // 错误描述
}
  1. 如果是其它未知错误,抛5XX,认为是服务器内部错误,而不是逻辑错误。

所以对于APP/WEB等客户端来说,很简单,如果发现2XX,则认为成功,直接获取数据。如果非2XX,则是失败,直接取code和message,展现到前台。

但是对于微服务之间的调用,就要区分是"4XX-业务逻辑异常",还是"5XX-服务器异常"了。。。

REST返回码的选择

下面详细讲一下HTTP STATUS的选择问题。

关于HTTP返回码,看了很多参考(论战),"大概"可以这样选择:

成功: 2XX系列

  • 200 OK // 查询、删除成功用这个
  • 201 CREATED // 新增、修改时用这个。且返回BODY中无任何信息。

业务异常: 4XX系列

  • 400 BAD_REQUEST // 现在有很多人在业务异常时抛这个错。但400要慎重使用。稍后解释。
  • 404 NOT_FOUND // 查询不到结果时用这个
  • 403 FORBIDDEN // 这个也慎重使用。
  • 409 CONFLICT // 业务异常时,可以用这个。

主机异常:5XX系列

  • 500 INTERNAL_SERVER_ERROR // 对于未知异常,统一用这个了
  • 503 SERVICE_UNAVAILABLE // Hystrix异常用这个

什么时候应该Fallback

2XX,成功,这个不用再讨论。

5XX,也相当明确,直接Fallback,这个也不用讨论。

4XX,可以一律认为是业务逻辑异常(或者更精确的说,可以认为4XX中的某几个是业务异常)。这时候,应该是用if/else来处理这个异常,而不应该动用Hystrix来Fallback。

Feign在默认情况下,对于非2XX,都认为是异常。这个地方是有问题的。特别是对于404这种非常容易抛出的业务异常来说,没两下就circuit break了。

Feign的Issue里已经有人提过这个问题,后面的版本中已经提供了一个参数:decode404

可以看一下Feign的代码,位置在:

~/.m2/repository/io/github/openfeign/feign-core/9.5.0/feign-core-9.5.0.jar!/feign/SynchronousMethodHandler.class

 
 

所以在Client上可以这样设置:

@FeignClient(name = "marathon-lb", fallback = FooBarClientFallback.class, decode404 = true)
@RequestMapping(value = "/foo/bar")
public interface FooBarClient {
... ...
}

只需要加入decode404 = true这一个参数,Feign对于2XX和404 ,都不会走Fallback了。

排除404,已经基本上够用了,如果想把409、400等status也加到例外中,可以重写一下Feign的errorDecoder。

关于4XX错误

刚才提到的,如果把2XX,另外加上4XX,全部认为是正常业务逻辑,都不走Fallback,可不可行? 我想最好不要这样很笼统的设置,要看情况。

因为http status不全是服务端给出的,如果服务端与消费者之间隔着一些Nginx、HA、Kong这样的网关,那么情况可能就复杂了,网关也有可能抛出status。

例如当某个微服务宕机之后,Kong网关会直接返回400,这种情况下,很明显是应当Fallback的。

所以,在定义错误码时,要尽量避开400、403这种很溃常见的码,像409这样小众的,差不多可以放心使用。

这样,调用方就可以有针对性的对某几个4XX的status进行单独配置,配置为业务异常。

作者:bluexiii
链接:https://www.jianshu.com/p/8d47a4fc4e82
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

关于Feign的Fallback处理的更多相关文章

  1. SpringCloud Feign 之 Fallback初体验

    SpringCloud Feign 之 Fallback初体验 在微服务框架SpringCloud中,Feign是其中非常重要且常用的组件.Feign是声明式,模板化的HTTP客户端,可以帮助我们更方 ...

  2. feign的fallback操作

    Fallback可以帮助我们在使用Feign去调用另外一个服务时,如果出现了问题,走服务降级,返回一个错误数据,避免功能因为一个服务出现问题,全部失效. 依赖: <dependency> ...

  3. No fallback instance of type class found for feign client user-service(转)

    1.错误日志 在 feign 开启熔断,配置 fallback 类,实现当前接口的实现类时,报错信息如下: Error starting ApplicationContext. To display ...

  4. Feign使用Hystrix

    Feign使用Hystrix开发步骤 1.导入依赖spring-cloud-starter-hystrix 2.消费启动类开启@EnableCircuitBreaker 3.配置yml文件feign. ...

  5. springcloud(七) feign + Hystrix 整合 、

    之前几章演示的熔断,降级 都是 RestTemplate + Ribbon 和 RestTemplate + Hystrix  ,但是在实际开发并不是这样,实际开发中都是 Feign 远程接口调用. ...

  6. SpringCloud系列十六:Feign使用Hystrix

    1. 回顾 上文讲解了使用注解@HystrixCommand的fallbackMethod属性实现回退.然而,Feign是以接口形式工作的, 它没有方法体,前文讲解的方式显然不适用与Feign. 事实 ...

  7. SpringCloud Feign 之 超时重试次数探究

    SpringCloud Feign 之 超时重试次数探究 上篇文章,我们对Feign的fallback有一个初步的体验,在这里我们回顾一下,Fallback主要是用来解决依赖的服务不可用或者调用服务失 ...

  8. feign使用hystrix熔断的配置

    熔断器hystrix 在分布式系统中,每个服务都可能会调用很多其他服务,被调用的那些服务就是依赖服务,有的时候某些依赖服务出现故障也是很正常的. Hystrix 可以让我们在分布式系统中对服务间的调用 ...

  9. spring boot2X整合nacos一使用Feign实现服务调用

    服务调用有两种方式: A.使用RestTemplate 进行服务调用 查看 B.使用Feign 进行声明式服务调用 上一次写了使用RestTemplate的方式,这次使用Feign的方式实现 服务注册 ...

随机推荐

  1. 9.4-6 kill & killall & pkill

    kill:终止进程 能够终止你希望停止的进程. kill 命令的参数选项及说明 -l    列出全部的信号名称 -p    指定kill命令只打印相关进程的进程号,而不发送任何信号 -s    指定要 ...

  2. C++对象内存分布详解(包括字节对齐和虚函数表)

    转自:https://www.jb51.net/article/101122.htm 1.C++对象的内存分布和虚函数表: C++对象的内存分布和虚函数表注意,对象中保存的是虚函数表指针,而不是虚函数 ...

  3. java 并发包JUC下的CountDownLatch和CyclicBarrier的理解和区别

    推荐这篇帖子,讲得不错~ https://blog.csdn.net/liangyihuai/article/details/83106584

  4. 【无人机航空摄影测量精品教程】目录:摄影测量、Pix4d、EPS、CC、PhotoScan项目化作业流程及注意事项汇总

    目录 1. 专栏简介 2. 专栏地址 3. 专栏目录 1. 专栏简介 该专栏为目前最为热门的无人机航测内外业项目,主要内容包括:无人机航测外业作业流程(像控点布设.航线规划.仿地飞行.航拍)和内业数据 ...

  5. 解决latex数学公式渲染不正确及行内公式中文渲染乱码问题

    问题 之前数学OCR渲染数学公式用的 katex 来渲染,前端解决方案,我们的进行公式编写的时候是需要输入中文的,如: Fe_{2}O_{3} + 3 C O \stackrel{高温}{=} 2 F ...

  6. .NET5 WPF进阶教程

    一.概要 本系列将继<.net wpf快速入门教程>带领大家了解wpf,帮助各位在初级向中级过渡的中掌握基本该具备的能力.本系列视频长度大约在15分钟到30分钟左右,视频内容不仅仅会讲解技 ...

  7. 『动善时』JMeter基础 — 31、JMeter中BeanShell断言详解

    目录 1.BeanShell简介 2.Beanshell的内置变量和方法 3.BeanShell断言界面详解 4.BeanShell断言的使用 (1)测试计划内包含的元件 (2)登陆接口请求界面内容 ...

  8. 一篇文章弄懂 Java 反射的使用

    说到Java反射,必须先把 Java 的字节码搞明白了,也就是 Class , 大 Class 在之前的文章中,我们知道了Java的大Class就是类的字节码,就是一个普通的类,里面保存的是类的信息, ...

  9. 数据结构-几种Tree

    1.二叉查找树 或 二叉排序树 (BST) 性质:左子树的键值小于根的键值,右子树的键值大于根的键值. 2.平衡二叉树(AVL Tree) 它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且 ...

  10. 重新整理 mysql 基础篇————— mysql 事务[三]

    前言 简单整理一下事务. 正文 事务有四大特性: 1.原子性(atomicity) 一个事务必须被视为一个不可分割的最小单元. 2.一致性(consistency) 数据库总是从一个一致性的状态转换到 ...