xianhu / PSpider

简单易用的Python爬虫框架,QQ交流群:597510560
https://github.com/xianhu/PSpider
BSD 2-Clause "Simplified" License
1.83k stars 504 forks source link

concur_insts 稳定性问题 #4

Closed Foristkirito closed 6 years ago

Foristkirito commented 7 years ago

以下面代码为例,self.pool.finish_a_task(TPEnum.URL_FETCH) 以上的任意代码出现问题,都可能造成线程异常退出,导致程序无法正常结束。比较简单的解决办法是加个 try ... catch

def work_fetch(self):
    # ----1
    priority, url, keys, deep, critical, fetch_repeat, parse_repeat = self.pool.get_a_task(TPEnum.URL_FETCH)

    # ----2
    code, content = self.worker.working(url, keys, critical, fetch_repeat)

    # ----3
    if code > 0:
        self.pool.update_number_dict(TPEnum.URL_FETCH, +1)
        self.pool.add_a_task(TPEnum.HTM_PARSE, (priority, url, keys, deep, critical, fetch_repeat, parse_repeat, content))
    elif code == 0:
        priority += (1 if critical else 0)
        self.pool.add_a_task(TPEnum.URL_FETCH, (priority, url, keys, deep, critical, fetch_repeat+1, parse_repeat))
    else:
        pass

    # ----4
    self.pool.finish_a_task(TPEnum.URL_FETCH)
    return True
xianhu commented 7 years ago

这个异常你有遇到过吗?

Foristkirito commented 7 years ago

在最后要结束的时候,not_fetcher, not_parser, not_saver 都是0,但是始终有一个 tasklog 也一直在打,退出不了,数据量比较大没有回溯看 log
后来我改成 try...catch 后发现最后,也是应该结束的时候,有 task_done() called too many times 的报错,正在找哪出现的问题。

xianhu commented 7 years ago

task_done() called too many times,我的理解是队列里放了10个item,但是调用了11此该函数。按照代码逻辑不应该出现这个问题。可以看一下你的代码吗?

Foristkirito commented 7 years ago

是那一部分的代码?

xianhu commented 7 years ago

如果方便的话,想看整个代码工程

xianhu commented 6 years ago

最近针对这个问题,我进行了大量的测试。抓取数据量超过亿级别,并且在多台机器上都进行了测试,并没有发现类似问题。暂时先关闭该问题了。