如何使用 Feign.Builder 实现 Sleuth Tracing?

Posted

技术标签:

【中文标题】如何使用 Feign.Builder 实现 Sleuth Tracing?【英文标题】:How to implement Sleuth Tracing With Feign.Builder? 【发布时间】:2018-06-21 00:52:24 【问题描述】:

我正在尝试将 Sleuth 集成到我们的系统中。如果我使用带有@FeignClient 注释的接口,一切正常。这些接口会自动检测,Sleuth 标头会通过 REST 调用传播。

但是,我们有一些现有的代码直接使用 Feign.Builder 和 Feign 注释接口(只是没有用 @FeignClient 注释)。这段代码添加了一些自定义的请求拦截器、编码器、代理等。

例如:

// Feign REST interface
public interface MyService 

    @RequestMapping(method = RequestMethod.GET, value = "/version")
    String getVersion();


// Creating the builder
Feign.Builder builder = Feign.builder();
builder.requestInterceptor(new MyCustomInterceptor());
// + adding proxy, encoder, decoder, etc

// Using the builder
MyService myService = builder.target(MyService.class, "http://localhost:8080/myservice");
myService.getVersion();

我希望这个旧代码能够传播 Sleuth 标头。有什么简单的方法可以把它连接起来吗?

(我想一种选择是重新设计我们的 Feign 接口以使用 @FeignClient 并重新设计所有自定义拦截器、编码器等的应用方式,但最终这可能会带来很多风险。)

我是否需要做一个特殊的请求拦截器来手动注入这些(例如从自动装配的 Tracer)?有没有一种干净的方法(或现有的类)来做到这一点?

【问题讨论】:

【参考方案1】:

我一直在与 Feign、FeignBuilder 和 zipkin 作斗争。 对我来说,使用 FeignClient 并在属性文件中配置 Feign,它起作用了。

@FeignClient(value = "ms-common--zipkin-test2")
public interface Client2 

@GET
@Path("/request1")
String request1(@QueryParam("payload") String payload);

在 application.yml 中

feign:
  client:
    config:
      ms-common--zipkin-test2:
        connectTimeout: 5000
        readTimeout: 5000
        loggerLevel: full
        requestInterceptors:
         - com.organization.mscommonzipkintest1.framework.client.FeignUserAgentInterceptor

我在那个包中创建了一个 FeignUserAgentInterceptor。

【讨论】:

【参考方案2】:

我终于明白了。

答案就在这里:https://github.com/spring-cloud/spring-cloud-sleuth/issues/594

当使用 Feign.Builder 时,它的 Client 需要被一个“Trace”实现包裹。

为此,我们只需声明一个客户端 bean,然后 spring/sleuth 将自动处理它的包装(因为 sleuth 在依赖项列表中)。

声明将类似于:

@Bean
public OkHttpClient okHttpClient() 
    return new OkHttpClient();

然后我们可以在构建客户端实现时将该客户端 bean 传递给构建器。

例如:

// autowiring the Client bean
@Autowired
private Client client;

// using the Client bean to build the Feign client
DemoClient demoClient = Feign.builder()
        .client(client)
        .target(DemoClient.class, "http://localhost:8200/demo");

这样做之后,一切似乎都正常了。我可以看到 Trace Id 被传播到远程 REST 服务。

【讨论】:

以上是关于如何使用 Feign.Builder 实现 Sleuth Tracing?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Cloud Feign 组成和配置

声明式HTTP客户端 - Spring Cloud OpenFeign

有没有办法在使用 SpringCloud OpenFeign 时为每个 Feign 实例创建不同的客户端?

与 IC 读卡器和 SLE5528 智能卡配合使用

APDU 命令读取 SLE4432/42 卡

使用 ACR38 读卡器从 SLE 4442 智能卡读取数据