美文网首页工作生活
关于httpClient请求夯住的问题

关于httpClient请求夯住的问题

作者: java_飞 | 来源:发表于2019-07-04 19:49 被阅读0次

    情景: 在生成环境里,平时跑了大半个月的程序突然有一天不正常了,其余的服务一切正常,接口请求等都没有异常,唯独有个定时任务不正常,通过日志可以判断出,程序被卡住了,导致后面的代码没有运行,从而没有打印出相关日志,这个问题感觉很诡异,由于本人比较菜,没有第一时间去想到去看堆栈,线程等信息,并且不会调优等,导致无法确切的定位出问题所在,但是查看代码可以大致得出问题所在,其余的都是简单的get,set代码基本没有问题,所有唯一问题只可能在http调用上面;

    通过网上查询,咨询大佬,得知到他们在用java做爬虫程序时也时长遇到这中情况,所以可以确定80%问题是出在http调用上面;

    问题1

    疑问??????
    http调用如果异常或者超时的情况下,程序应该会报错,而且打印出相关异常,但是我在日志里面并没有看到相关的日志信息,所有感绝这个问题十分诡异,但是网上又有博客说明apache httpclient 如果不设置超时时间的话,是会存在程序卡死现象,也就是标题所说的夯住,导致下面的代码无法运行;
    这里说明apache httpClient 可以设置三个超时时间:

    RequestConfig requestConfig = RequestConfig.custom()  
            .setConnectTimeout(5000).setConnectionRequestTimeout(1000)  
            .setSocketTimeout(5000).build(); 
    

    1.setConnectTimeout:设置连接超时时间,单位毫秒。
    2.setConnectionRequestTimeout:设置从connect Manager(连接池)获取Connection 超时时间,单位毫秒。
    3.setSocketTimeout:请求获取数据的超时时间(即响应时间),单位毫秒。 如果访问一个接口,多少时间内无法返回数据,就直接放弃此次调用。

    然后,我去查看我项目中使用的httpClient,发现并没有设置相关超时时间,由此我判定问题是出在这里;

    问题2:

    我用的是定时任务,为什么一个请求夯住会导致后面的都无法执行呢,不是应该到点重新开始执行?

    原因: 因为这里用的定时任务是spring自带的task,他是同步执行的,这一次不执行完会导致之后都无法执行,所有就存在了上述的情况,一个请求卡住,导致之后任务都不在执行;所以这也是一个问题,是否同步下图可知,代码很简单买我就不写了:

    image.png

    解决思路:
    下面有3种解决思路:
    1.由于问题是出在http调用这边,没有设置超时时间导致的,所有就给http的每次调用设置超时时间,这样如果报错了,只要下一次任务重新进来,任务还是可以执行到;

    2.换一个定时任务框架,使用quartz,这个是异步的,也就是这一次调用不成功,只要下次时间到了,这个任务还是会执行,
    猜想:但是如果卡住的情况多了的话,会不会存在线程不够用的情况?因为如果在http这边卡住,这种情况多了的话,那么好多线程都会被挂起,很可能导致out of memory吧;

    3.当然最好的办法肯定是以上两种结合起来,这样的话即使卡住了,但是到了超时时间,这个线程也会空闲出来,而且也不避免了超时时间内任务无法得到运行的情况;

    还有人会提出不是用httpClient,用httpConnection;

    当然使用这个类库的话,我没有查找太多资料,但是这个类也有设置超时时间的方法,我觉得也可能会存在上述我说的情况,代码如下:

    httpConnection.setConnectTimeout(TIMEOUT);//建立连接的超时时间
            httpConnection.setReadTimeout(TIMEOUT);//传输数据的超时时间
    

    java内的http调用问题分析到这里,希望能帮到大家,看过觉得有用的可以点个喜欢收藏一下(QQ:1107156537)

    相关文章

      网友评论

        本文标题:关于httpClient请求夯住的问题

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