• SpringCloud FeignClient的坑(httpClient连接池的使用)


    SpringCloud FeignClient的坑(httpClient连接池的使用)

    前言

    在头条上已经发布过不少的文章了,根据文章的浏览量来看,go语言的市场需求明显是小于java的需求量的,最近也开始发布一下以前使用java和springcloud,springboot里遇到的一些避坑文章; 个人感觉go在云原生这个场景里将会不断的被发展,在云原生环境下,没有任何一个语言可能和其匹敌,RUST也许会有一定的竞争压力。 作为service mesh未来的云环境架构, springcloud的原有项目会慢慢的转换; 先说了些感悟, 今天要分享的是OpenFeign里的一个小坑。 OpenFeign是springcloud里用的比较多的http RPC的一个架构, FeignClient是这个架构中的一个Client的入口点。

    现象:
    压力测试

    结果发现,并发线程数较多(>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.(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调用代码
    如下:

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

    上面是autoconfiguration的方式对feignClient进行配置。  可以看到有三种方式, 分别是HttpClientFeignLoadBalancedConfiguration.class,        OkHttpFeignLoadBalancedConfiguration.class,
     DefaultFeignLoadBalancedConfiguration.class

    这三种方式, 其中最后一种方式DefaultFeignLoadBalancedConfiguration是默认方式,也就是直接通过Httpclient进行http的调用,不使用连接池的方式,只有上面两种方式是支持连接池的方式, Openfeign组件通过类型ConditionONClass的方式,进行条件配置,如果引入了OKHttpClient或者Apache HttpClient的包才会使用到http的连接池, 由于默认是没有import这里的两个包,所以默认以不带连接池的实现方式来实现httpclient,也就出现上面的问题。 

    知道了问题所在,解决的方法,就是引入相应的包即可。

  • 相关阅读:
    RFID技术在危险废物管理中的应用解决方案
    Linux操作系统 - 进程控制
    大数据1星笔试题_220621
    基于降阶扩张状态观测器的逆变系统重复控制设计
    【OpenCV实现图像:用OpenCV图像处理技巧之白平衡算法2】
    CYEZ 模拟赛 7
    Java-package和import语句
    Linux系统环境下项目部署
    Word控件Spire.Doc 【加密解密】教程(二):在 C#、VB.NET 中锁定 Word 文档的指定部分
    【Node.js】深度解析常用核心模块-fs模块
  • 原文地址:https://blog.csdn.net/inthirties/article/details/126583997