关于 MongoDB 在 concurrent.futures.PoolProcess 开启多进程下的报错解决办法 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
DesmondLeo
V2EX    Python

关于 MongoDB 在 concurrent.futures.PoolProcess 开启多进程下的报错解决办法

  •  
  •   DesmondLeo 2022-03-03 18:09:21 +08:00 2883 次点击
    这是一个创建于 1317 天前的主题,其中的信息可能已经有所发展或是发生改变。

    该帖子有点长哈...不好意思

    是这样,这是一个爬虫项目的主程序入口,下面代码里面的 mongo_cOnnection= mongo_connect( cOnnect= False, server_selection_timeoutMS = 60000 ) 用来连接数据库,但我在服务器上测试的时候发现一直提示 timeout 报错(详见上面的报错信息)

    我查了不少文章,看到不少说是要在多进程开启后再给每一个进程连接 mongoDB ,所以一开始我将连接数据库的代码放到了三个爬取程序的开头(就是下文那三个 parser() 函数),但依旧报同样的错; 然后我在 GitHub 上面看到了一个关于多进程下 Pymongo 提示 UserWarning 的解答,里面提到了可以添加 cOnnect= False 参数,但我试过还是不行,应该问题也不在这里; 然后我又修改了 serverSelectionTimeoutMS ,将时间改为 60 秒(嗯当然还是没用)

    求大佬指点一下怎么在使用 concurrent.futures 开启多进程的情况下连接 mongoDB!谢谢!

    下面贴了环境、报错信息和代码

    测试环境

    CentOS 7.8.2003
    python = 3.7.7

    依赖包版本
    pymOngo== 4.0.1
    concurrent:Python 自带

    报错信息

    该信息来源于日志

    ERROR: 192.168.1.202:27017: timed out, Timeout: 60.0s, Topology Description: <TopologyDescription id: 622086a8ea6efc1d07de056f, topology_type: Unknown, servers: [<ServerDescription ('192.168.1.202', 27017) server_type: Unknown, rtt: None, error=NetworkTimeout('192.168.1.202:27017: timed out')>]> 

    主程序脚本

    import pymongo from concurrent.futures import PoolProcessExecutor, as_completed # 导入外部自定义模块 import ... def run_spider(log_recorder, proxy): """ 主程序,可启动目标网页的爬取程序 :param log_recorder: 日志记录工具 :param proxy: 项目专用代理 :return: """ log_recorder.info( "Spider starts running! :)" ) try: # 连接数据库 mongo_cOnnection= mongo_connect( cOnnect= False, server_selection_timeoutMS = 60000 ) try: # 主程序运行 council_parser( mongo_connection, log_recorder, proxy ) gd_province_parser( mongo_connection, log_recorder, proxy ) market_supervisor_parser( mongo_connection, log_recorder, proxy ) log_recorder.info( "Spider ran over! :)" ) # 爬取结束后断开数据库连接 mongo_connection.close() except Exception as e: log_recorder.error(f"{e} :(") # 出现异常依然断开连接 mongo_connection.close() except Exception as e: log_recorder.error(f"{e}:(") if __name__ == "__main__": # 设置日志工具 regulation_logger = spiderLogger.get_logger('regulation') # 设置代理 proxy = get_proxy() # 多进程并发 with ProcessPoolExecutor(max_workers = 8) as executor: fs = [] futures = executor.submit(run_spider, regulation_logger, proxy) fs.append(futures) for future in as_completed(fs): result = future.result() 
    第 1 条附言    2022-03-04 10:18:46 +08:00

    mongo_connent方法代码:

    def mongo_connect(cOnnect= True, server_selection_timeoutMS: int = 60000): mongo_cOnnection= MongoClient( server = settings.DATABASES['mongodb']['HOST'], port = settings.DATABASES['mongodb']['PORT'], username = settings.DATABASES['mongodb']['USER'], password = settings.DATABASES['mongodb']['PASSWORD'], db = settings.DATABASES['mongodb']['db'], cOnnect= connect, serverSelectiOnTimeoutMS= server_selection_timeoutMS ) return mongo_connection 
    9 条回复    2022-03-04 10:22:08 +08:00
    fgwmlhdkkkw
        1
    fgwmlhdkkkw  
       2022-03-03 18:24:51 +08:00
    ……你用命令行能连上数据库吗?
    DesmondLeo
        2
    DesmondLeo  
    OP
       2022-03-03 18:37:23 +08:00
    @fgwmlhdkkkw 命令行可以
    vvhhaaattt
        3
    vvhhaaattt  
       2022-03-03 18:54:43 +08:00 via Android
    我觉得先确认你不用多进程时,代码能正常连接不。
    ClericPy
        4
    ClericPy  
       2022-03-03 23:01:38 +08:00
    1. mongo_connect 哪来的有点陌生, 这东西不好调试的话临时闭包到 run_spider 里测试一下? 怀疑有些变量传递到进程里面有地方不太对, 多进程类似于各种并行计算的一个特点就是: 尽量无状态无副作用, 里面的各种依赖 /参数 /上下文都尽量隔离干净
    2. 本地调试可以运行但线上不行的话, 可能的地方特别多(难怪虚拟化和 go 那么火了)
    2.1 最大可能是网络本身就不通(防火墙规则啊, 网卡 ip 不对啊, 非局域网啊, 非开放端口啊), 但是如果关了多进程会 ok, 网络应该不是问题. 可以临时把 PoolProcessExecutor 改成多线程那个, 反正接口一样的, 而且爬虫这玩意本来就没必要多进程
    2.2 Python 版本有区别, 个别底层依赖有差异, 这个少见但也遇到过
    2.3 第三方依赖的版本或者 C 依赖有差异, 尽量排除这种情况, 以前我遇到过类似情况, 换个版本居然就通了
    2.4 检查是不是每个进程都超时, 有一定可能是程序里面或者 mongodb 那边有奇怪的死锁
    ch2
        5
    ch2  
       2022-03-03 23:30:34 +08:00 via iPhone
    你都没有指定 host 跟 port ,让它去连啥啊
    dudu2017
        6
    dudu2017  
       2022-03-03 23:52:41 +08:00
    mongo_connect 方法是你自己封装的吧,这里的代码是不是也应该贴一下?
    DesmondLeo
        7
    DesmondLeo  
    OP
       2022-03-04 10:08:53 +08:00
    @vvhhaaattt 不用的时候可以
    DesmondLeo
        8
    DesmondLeo  
    OP
       2022-03-04 10:13:40 +08:00
    @ch2 那个 mongo_connect 是封装的方法,会读取配置文件里面的数据库配置
    @dudu2017 这个确实是封装的,但其实也只是内部调用了下 MongoClient 这个类,参数都从配置文件里面读取
    DesmondLeo
        9
    DesmondLeo  
    OP
       2022-03-04 10:22:08 +08:00
    @ClericPy 啊好详细的回复,我昨天后来在排查的时候感觉应该是死锁(感觉),那个 ThreadProcessExecutor 昨天我也试过了,效果一样 2333 ,应该不是这个问题,我今天再看看怎么处理
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1025 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 18:38 PVG 02:38 LAX 11:38 JFK 14:38
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86