首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用假构建器请求不会将trace-id、span-id发送给子客户端,但使用rest模板会显示子客户端上的所有标头

使用假构建器请求不会将trace-id、span-id发送给子客户端,但使用rest模板会显示子客户端上的所有标头
EN

Stack Overflow用户
提问于 2021-02-12 15:36:22
回答 1查看 791关注 0票数 3

我正在使用Feign Builder发出顺序请求。没有x-b3-traceid,x-b3-spanid ..在请求的标题中。这就是为什么日志my last client会出现在zipkin上。

我使用了spring boot 2.4.2、spring cloud 2020.0.0、feign-core 10.10.1、feign-okhttp 10.10.1。我已经尝试了spring-cloud-openfeign,并且达到了想要的效果。但是我不想使用这个库。这里有使用Feign Builder和Rest模板的要求。我在zipkin上看不到同样的日志。

我的Client1应用。我正在发送请求

http://localhost:8082/

代码语言:javascript
运行
复制
import feign.Client;
import feign.Feign;
import feign.RequestInterceptor;
import feign.codec.Decoder;
import feign.codec.Encoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import sample.feign2.Client2Feign;

import javax.servlet.http.HttpServletRequest;
@RestController
public class SampleController {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private Client client;

    @Bean
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }

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

    @GetMapping("/hello/feignBuilder")
    public String sayHelloFeignBuilder(HttpServletRequest httpServletRequest){
        logger.info("Send to request client2");
        Client2Feign client2Feign = Feign.builder()
                .client(client)
                .decoder(new Decoder.Default())
                .encoder(new Encoder.Default())
                .target(Client2Feign.class, "http://localhost:8082/");
       return client2Feign.sayHelloFeignBuilder();
    }

    @GetMapping("/hello/say")
    public String sayHelloFeignBuilder1(){
        return "Hello";
    }

    @GetMapping("/hello/rest")
    public String sayHelloRest(){
        System.out.println(tracer.currentSpan());
        logger.info("Inside rest 1");
        String baseUrl = "http://localhost:8082/sayHelloRest";
        String response = (String) restTemplate.exchange(baseUrl, HttpMethod.GET, null, String.class).getBody();
        logger.info("The response received by client2 is " + response);
        return response;
    }

}

这是我的client1应用程序的yml。我在client2和clint3的其他客户端应用程序上使用相同的yml conf。仅更改端口和应用程序名称。

代码语言:javascript
运行
复制
server:
  port: 8081
spring:
  application:
    name: euraka-client1
  zipkin:
    enabled: true
    service.name: euraka-client1
    sender.type: web
    base-url: http://localhost:9411
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka
  instance:
    preferIpAddress: true

这是我在Client2应用程序上的杰作。

代码语言:javascript
运行
复制
import feign.RequestLine;

public interface Client2Feign {

    @RequestLine("GET /sayHelloBuilder")
    String sayHelloFeignBuilder();

}

这里实现了ClientFeign2。

代码语言:javascript
运行
复制
import org.springframework.web.bind.annotation.GetMapping;

import javax.servlet.http.HttpServletRequest;

public interface FeignBuilderController {

    @GetMapping("/sayHelloBuilder")
    String sayHelloBuilder(HttpServletRequest httpServletRequest);

    @GetMapping("/sayHelloRest")
    String sayHelloRest(HttpServletRequest httpServletRequest);
}
代码语言:javascript
运行
复制
import feign.Client;
import feign.Feign;
import feign.RequestInterceptor;
import feign.codec.Decoder;
import feign.codec.Encoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import sample.feign.Client3Feign;
import sample.feign2.Client2Feign;

import javax.servlet.http.HttpServletRequest;

@RestController
public class FeignBuilderControllerImpl implements FeignBuilderController{

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private Client client;

    @Bean
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }

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

    @Override
    public String sayHelloBuilder(HttpServletRequest httpServletRequest) {
        logger.info("Send to request client3");
        Client3Feign client3Feign = Feign.builder()
                .client(client)
                .decoder(new Decoder.Default())
                .encoder(new Encoder.Default())
                .target(Client3Feign.class, "http://localhost:8083/");
        return client3Feign.sayHelloFeignBuilder3();
    }

    @Override
    public String sayHelloRest(HttpServletRequest httpServletRequest) {
        logger.info("Inside rest 2");
        String baseUrl = "http://localhost:8083/sayHelloRestClient3";
        String response = (String) restTemplate.exchange(baseUrl, HttpMethod.GET, null, String.class).getBody();
        logger.info("The response received by client3 is " + response);
        return response;
    }

这是我在Client3应用程序上的杰作。

代码语言:javascript
运行
复制
import feign.RequestLine;

public interface Client3Feign {

    @RequestLine("GET /sayHelloBuilderClient3")
    String sayHelloFeignBuilder3();

}

这里实现了Client3伪装。

代码语言:javascript
运行
复制
import javax.servlet.http.HttpServletRequest;

public interface FeignController3 {

    @GetMapping("/sayHelloBuilderClient3")
    String sayHello3(HttpServletRequest httpServletRequest);

    @GetMapping("/sayHelloRestClient3")
    String sayHelloRest3(HttpServletRequest httpServletRequest);
}
代码语言:javascript
运行
复制
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

@RestController
@RequestMapping
public class FeignController3Impl implements FeignController3 {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public String sayHello3(HttpServletRequest httpServletRequest) {
        logger.info("Response returned from client3");
        return "Hello from client3 using FeignClientBuilder";
    }

    @Override
    public String sayHelloRest3(HttpServletRequest httpServletRequest) {
        logger.info("Response returned from client3");
        return "Hello from client3 using RestClient";
    }
}

来自client3的pom.xml和我在client2/pom上使用的client3与client1相同。

代码语言:javascript
运行
复制
4.0.0
    oguzhan.example
    client3
    1.0-SNAPSHOT
    
        UTF-8
        UTF-8
        11
    
    
        
            
                org.springframework.boot
                spring-boot-dependencies
                2.4.2
                pom
                import
            
            
                org.springframework.cloud
                spring-cloud-dependencies
                2020.0.0
                pom
                import
            
        
    
    
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
        
        
            org.springframework.cloud
            spring-cloud-starter-sleuth
        
        
            org.springframework.cloud
            spring-cloud-sleuth-zipkin
        
        
            io.github.openfeign
            feign-core
        
        
            io.github.openfeign
            feign-okhttp
        
    
    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    
                        build-info
                        
                            build-info
                        
                    
                
            
            
                org.apache.maven.plugins
                maven-compiler-plugin
                3.8.1
                
                    ${java.version}
                    ${java.version}
                    ${java.version}

diff-feign-rest-image

feign-zipkin-img

feign-request-img

rstlet-rest-tmplte-img

rest-zipkin-img

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-15 18:01:11

这个问题可能与您通过以下方式手动创建Feign builder有关

工厂方法。我们不能给那个电话装上仪器。您应该创建bean (通过

)并将其注入到您的代码中。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66167917

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档