Spring Cloud Netflix:使用 Feign 处理远程服务错误
Posted
技术标签:
【中文标题】Spring Cloud Netflix:使用 Feign 处理远程服务错误【英文标题】:Spring Cloud Netflix: Remote service error handling with Feign 【发布时间】:2016-12-17 21:33:15 【问题描述】:我们正在尝试将 Spring Cloud Netflix 放入生产环境。现在我们遇到一个关于业务逻辑错误处理的问题。
我们使用 Feign 作为 HTTP REST 客户端。微服务 A 需要调用部署在不同 JVM(或物理服务器)中的微服务 B。微服务 B 可能会返回一些属于业务的错误消息。例如 A 需要向 B 查询订单信息,但订单 ID 可能不存在,因此 B 必须返回错误消息,告诉 A 该订单不存在。 A 必须从返回信息中做if-else
判断,判断是否有错误,那么代码会像下面sn-p:
//remoteServiceA is an interface annotated with @FeignClient
resultA = remoteServiceA.foo();
if (resultA.hasError)
else
resultB = remoteServiceB.foo();
if (resultB.hasError)
else
// ... ...
if-else
太多了,不够优雅。我们想要的是remoteServieA.foo()
可以抛出一个自定义的运行时异常比如OrderNotExistException
。有什么想法可以实现这个目标吗?
【问题讨论】:
本着真正的 REST API 精神,返回的 http 错误代码应该是不言自明的。因此,如果您正在查询订单(资源)并获得 404,则表示“未找到资源”,即“未找到订单”。 【参考方案1】:我已经解决了这个问题。
我自定义了Feign的ErrorDecoder
组件,可以根据HTTP原始响应抛出自己的异常。
【讨论】:
【参考方案2】:如果您启用了 Hystrix,您应该能够将 serviceA.foo() 包装在 try 块中并在远程服务中引发异常。
try
serviceA.foo();
catch(HystrixRuntimeException ex)
throw new OrderNotExistException("Error message");
您仍然必须考虑到,如果您的远程服务没有响应,或者发生其他错误,您可以捕获这种异常。也许您可以找到有关发生的异常的信息并决定是否应该抛出异常。
我想到的第一件事,但在我的一个项目中工作。
【讨论】:
这将再次导致OP正在谈论的if-else判断。以上是关于Spring Cloud Netflix:使用 Feign 处理远程服务错误的主要内容,如果未能解决你的问题,请参考以下文章
将 apache kafka 与 Spring Cloud netflix 堆栈一起使用
spring-cloud-starter-eureka-server 和 spring-cloud-starter-netflix-eureka-server的区别
Spring Cloud / Netflix OSS 中的负载均衡
Spring Cloud Netflix:使用 Feign 处理远程服务错误
随手记录关于spring-cloud-starter-eureka-server 和 spring-cloud-starter-netflix-eureka-server