Feign http 请求跟踪
背景:服务请求卡顿,服务端时延小;跟踪feign请求定位服务卡段位置
ribbon、feign、hystrix场景 调用链如下
SynchronousMethodHandler.invoke
LoadBalancerFeignClient.execute
RetryableFeignLoadBalancer.execute
TraceFeignClient.EXECUTE
feign.Client.execute
HttpURLConnection
早期跟踪zuul 类似场景发现请求使用apache http cleint,原以为该工程也是,定位不到请求,源码跟踪下来发现最后用的竟然是HttpURLConnection,和作者表述的不一样
Dalston.SR4 or Edgware.RELEASE. When using Feign or Ribbon you can use either the Apache HTTP Client (default) or the OK HTTP Client.
继续跟踪
Feign 默认使用apache httpclient,但需要一些条件,否则直接使用(DefaultFeignLoadBalancedConfiguration) jdk HttpURLConnection作为http 客户端
满足条件:
@ConditionalOnClass({ ILoadBalancer.class, Feign.class })
@Configuration
@AutoConfigureBefore(FeignAutoConfiguration.class)
@EnableConfigurationProperties({ FeignHttpClientProperties.class })
//Order is important here, last should be the default, first should be optional
// see https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653
@Import({ HttpClientFeignLoadBalancedConfiguration.class,
OkHttpFeignLoadBalancedConfiguration.class,
DefaultFeignLoadBalancedConfiguration.class })
public class FeignRibbonClientAutoConfiguration {
@Bean
@Primary
@ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate")
public CachingSpringLoadBalancerFactory cachingLBClientFactory(
SpringClientFactory factory) {
return new CachingSpringLoadBalancerFactory(factory);
}
@Bean
@Primary
@ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate")
public CachingSpringLoadBalancerFactory retryabeCachingLBClientFactory(
SpringClientFactory factory,
LoadBalancedRetryPolicyFactory retryPolicyFactory,
LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory,
LoadBalancedRetryListenerFactory loadBalancedRetryListenerFactory) {
return new CachingSpringLoadBalancerFactory(factory, retryPolicyFactory, loadBalancedBackOffPolicyFactory, loadBalancedRetryListenerFactory);
}
@Bean
@ConditionalOnMissingBean
public Request.Options feignRequestOptions() {
return LoadBalancerFeignClient.DEFAULT_OPTIONS;
}
}
@Configuration
@ConditionalOnClass(ApacheHttpClient.class)
@ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true)
class HttpClientFeignLoadBalancedConfiguration {
使用方式: 配置文件及pom引入
feign:
httpclient:
enabled: true
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
<version>9.5.0</version>
</dependency>
使用Apache HTTP Client 好处在于,其内部做了一些优化扩展,另外日志打印友好,结合logback可以很方便的跟踪到具体执行关键节点,为了尽可能小的跟踪http 连接、发送、接收、释放过程,开启如下类debug日志
org.apache.http.impl.conn.DefaultHttpClientConnectionOperator
org.apache.http.conn.HttpClientConnectionOperator
org.apache.http.impl.execchain.MainClientExec
org.apache.http.impl.conn.PoolingHttpClientConnectionManager