美文网首页程序员
Http 爬虫 socketRead0

Http 爬虫 socketRead0

作者: 瑶瑶小仙女 | 来源:发表于2019-03-15 11:32 被阅读0次

    1、昨天线上出了个问题:我们线上的一个爬虫任务一直没有执行完毕,导致后面其他的任务跑的数据出错。发现问题之后,立刻找运维帮忙dump线上机器的日志来看:

    我们可以看到线程的状态还是runnable,然后看下线程的是阻塞在了socketRead0,因为之前有遇到过类似的问题就是MySQL的查询语句,从线程池中拿连接的时候没有校验连接的有效性导致拿不到连接,然MySQL的连接超时时间是默认的8小时。导致任务一个无效的线程,拿阻塞了8个小时才断开连接,问题当然是毁灭性的了。当然缺少有效性的校验和超时时间的设置是必要的,但是任务的监控添加也是有必要的。这个后面在说。

    今天发生的这个问题是由于DefaultHttpClient这个不推荐使用的客户端引起的,具体我们项目中的代码是这样使用的:

    问题就出在这句上面:get.setConfig(RequestConfig.custom().setConnectTimeout(Constant.TIMEOUT)

                    .setSocketTimeout(Constant.TIMEOUT).build());//10秒钟超时时间

    这个超时时间的设置是不对的。我们跟着源码进去,我这里贴出非重要的路径:

    当我们跟着源码到DefaultRequestDirector的exectue的方法的时候就差不多要切入正题了。下面咱们具体看看一个特别重要的方法tryConnect,他里面给我们会设置连接的超时时间等信息。

    tryConnect是一个内部方法,先检查是否当前连接是否是开启的,没有就会开启,进入到这个open方法中。

    可以看到连接是有的上一个方法返回的open属性的值是false。那么就去开启这个连接。结合上一步我们可以知道这个方法是需要设置超时时间等信息的。同事我们也可以看到poolEntry连接池中的信息,创建时间就是我Test启动的时间,超时时间是个特别大的值。

    开启的时候最终会走到PlainSocketFactory:

    你会发现他是从HttpParams params里面取值的。而不是我们代码中设置的样子。

    到此问题找到了,具体的解决办法有没有呢,当然有啊,而且还不只一个:

    解决办法:

    1.用下面的这种方式设置参数就是OK的啦。因为她就是按照下面的方式取值的么。

    2.第二种不用这个废弃的方式了。这种方式呢大家猜也难能猜到了,她设置值的时候是直接加载的config,就是咱们构造的这个socketConfig啦。大家有兴趣就跟进源码中去看看了。

    第二章fa

    debug源码真的很爽。

    相关文章

      网友评论

        本文标题:Http 爬虫 socketRead0

        本文链接:https://www.haomeiwen.com/subject/jydqmqtx.html