4

有关代码,请参阅我的微型 4 类github 项目

我正在使用 Spring FeignClients 连接到休息服务。这是 Feign 客户端在其基本(非异步)形式中的样子:

@FeignClient(value="localhost:8080/products", decode404 = true)
public interface ProductClient {
    @RequestMapping(value="/{id}")
    Product getById(@PathVariable("id") String id);
}

现在我想使用 Observable 异步执行此操作。Spring 文档中严重缺乏这方面的信息,只有一小段内容告诉您使用 HystrixCommand。就是这样,没有解释,没有示例代码。

在另一篇博文中,有人告诉我改用 HystrixObservable。所以我尝试了:

@FeignClient(value="localhost:8080/products", decode404 = true)
public interface ProductClient {
    @RequestMapping(value="/{id}")
    HystrixObservable<Product> getById(@PathVariable("id") String id);
}

无论哪种方式,使用 HystrixCommand 或 HystrixObservable,它都会向我抛出错误: com.fasterxml.jackson.databind.JsonMappingException:无法构造 com.netflix.hystrix.HystrixObservable 的实例

我理解为什么会出现这个错误,因为 Spring Boot 会自动将 Decoder 附加到 FeignClient 以使用 Jackson 反序列化响应。并且将响应反序列化为的类型是从返回值派生的。

我可以尝试配置自定义解码器或手动构建 Feign 客户端,但这违背了 Spring Boot 的全部目的:它自动工作(尽管在这里和那里有一些配置)。

所以我的问题是:这应该如何工作?

4

2 回答 2

1

如果有人在升级到 spring-cloud:1.3.+ 后开始出现此错误,请确保您启用了 hystrix-feign。

feign.hystrix.enabled=true

这是为了让 feign 默认情况下不会在 hystrix 命令中包装调用。

https://github.com/spring-cloud/spring-cloud-netflix/issues/1277

于 2017-05-25T21:22:01.737 回答
1

如果您将返回类型指定为 aHystrixCommand<Product>或 RxJava 中的任何一个,Observable<Product>或者Single<Product>而不是 aHystrixObservable<Product>它应该可以工作。

我相信 usingHystrixObservable不起作用的原因是因为它是一个接口,并且 Jackson 默认不会映射到接口等抽象类型,正如您可能在堆栈跟踪中看到的那样:

> abstract types either need to be mapped to concrete types, have custom
> deserializer, or contain additional type information

HystrixCommand然而,是HystrixObservable接口的实现,所以杰克逊可以很容易地映射到它。

如果你查看Feign 的 Hystrix 模块HystrixInvocationHandler,你会看到它能够返回的其他类型;我在上面列出的那些以及 RxJava 的. Tassos Bassoukos 链接的文档也列出了这些类型。Completable

如果您正在寻找异步且非阻塞的东西,那么可能值得一试 Feign Vertx,因为我相信 Feign 可以是异步但阻塞的。关于非阻塞 Feign 的讨论在这里

希望有帮助!

于 2017-03-12T23:28:26.437 回答