天天看點

SpringCloud FeignClient的坑(httpClient連接配接池的使用)

SpringCloud FeignClient的坑(httpClient連接配接池的使用)

前言

在頭條上已經釋出過不少的文章了,根據文章的浏覽量來看,go語言的市場需求明顯是小于java的需求量的,最近也開始釋出一下以前使用java和springcloud,springboot裡遇到的一些避坑文章; 個人感覺go在雲原生這個場景裡将會不斷的被發展,在雲原生環境下,沒有任何一個語言可能和其匹敵,RUST也許會有一定的競争壓力。 作為service mesh未來的雲環境架構, springcloud的原有項目會慢慢的轉換; 先說了些感悟, 今天要分享的是OpenFeign裡的一個小坑。 OpenFeign是springcloud裡用的比較多的http RPC的一個架構, FeignClient是這個架構中的一個Client的入口點。

SpringCloud FeignClient的坑(httpClient連接配接池的使用)

現象:

壓力測試

結果發現,并發線程數較多(>40)時,持續一段時間後,請求總數差不多達到100萬時,開始出現請求失敗。這個錯誤比例在10%~30%之間。

看日志,發現錯誤有兩種:

一種是ribbon報找不到目标服務,錯誤資訊如下:

Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client: halo-framework-example-server

    at com.netflix.loadbalancer.LoadBalancerContext.getServerFromLoadBalancer(LoadBalancerContext.java:483)

    at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:184)

    at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:180)

    at rx.Observable.unsafeSubscribe(Observable.java:10327)

    at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:94)

    at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:42)

    at java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:1.8.0_152]

    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_152]

    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_152]

    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_152]

    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_152]

    at java.net.Socket.connect(Socket.java:589) ~[na:1.8.0_152]

    at sun.net.NetworkClient.doConnect(NetworkClient.java:175) ~[na:1.8.0_152]

    at sun.net.www.http.HttpClient.openServer(HttpClient.java:463) ~[na:1.8.0_152]

    at sun.net.www.http.HttpClient.openServer(HttpClient.java:558) ~[na:1.8.0_152]

    at sun.net.www.http.HttpClient.<init>(HttpClient.java:242) ~[na:1.8.0_152]

    at sun.net.www.http.HttpClient.New(HttpClient.java:339) ~[na:1.8.0_152]

    at sun.net.www.http.HttpClient.New(HttpClient.java:357) ~[na:1.8.0_152]

檢視feignclient調用代碼

如下:

@Import({ HttpClientFeignLoadBalancedConfiguration.class,
    OkHttpFeignLoadBalancedConfiguration.class,
    DefaultFeignLoadBalancedConfiguration.class })
public class FeignRibbonClientAutoConfiguration {      
@Configuration
@ConditionalOnClass(ApacheHttpClient.class)
@ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true)
class HttpClientFeignLoadBalancedConfiguration {