因为项目需要,需要使用quartz定时器,实现一个爬虫功能,远程爬取一些数据,之前都是从一个网站(即单一来源)进行数据爬取,爬取成功则更新缓存,爬取失败则忽略,后来为了防止数据水分过大,需要从多个类似的网站都进行爬取,然后取平均值。当时为了加快爬取效率,使用了CountDownLatch,配合多个线程对多个数据来源进行爬取。开发和测试时都没问题,很正常,直到某一天我们发现数据没变化了,排查服务器日志发现,每次程序不正常时都是因为某个或多个远程服务器宕机或者连接超时导致的。我之前的代码大概表述如下:
#先创建一个downLatch对象:
CountDownLatch downLatch = new CountDownLatch(4);
#然后在每个爬虫线程中,爬取成功后,执行:
downLatch.countDown();//计数器-1
最开始查找资料的想法是:因为httpclient默认使用了长链接导致的,因为服务器压力大,导致响应超时,而我们的爬虫没有把连接释放,从而导致远程服务器不在响应我们爬虫请求。
所以我们就声明爬虫不保持长链接,设置HttpGet对象的请求头 :
get.setHeader("Connection","close");
结果程序跑了1周左右还是有这个问题,然后有一天突然想到,是否会是多线程爬取时,因为某个线程超时时间过大,超时抛出异常,从而计数器没有归零,从而导致主线程堵塞等等? 然后顺着这个思路,把代码进行了改造:
之前主线程等待其他爬虫线程执行完毕后,继续执行使用了
downLatch.await();
完善方法:把以上代码中,给主线程设置一个最大等待超时时

在使用CountDownLatch实现多线程爬虫时,由于线程异常未使计数器归零,导致主线程堵塞。通过设置最大等待超时时间解决此问题,确保爬虫线程的正确同步。
最低0.47元/天 解锁文章
1897

被折叠的 条评论
为什么被折叠?



