作者小头像 Lv.3
367 成长值

个人介绍

这个人很懒,什么都没有留下

感兴趣或擅长的领域

暂无数据
个人勋章
  • 活跃之星
成长雷达
340
27
0
0
0

个人资料

个人介绍

这个人很懒,什么都没有留下

感兴趣或擅长的领域

暂无数据

达成规则

发布时间 2026/10/04 17:26:11 最后回复 yd_257405204 2026/10/29 09:43:48 版块 数据库
37 4 0
他的回复:
先别急着换框架。把“断”先变成可观测的退出,再谈修复:入口加 faulthandler.enable(),主循环用 try/except 包住并记录退出码;137 先查 OOM(dmesg -T | grep -i "killed process",容器看 OOMKilled),143 查调度器或超时,1 才是业务异常。这样能避免把“被系统杀掉”误判成“代码有 bug”。我自己的最小改法分三块。第一,任务状态落 SQLite,一个 URL 一个事务:CREATE TABLE task(url TEXT PRIMARY KEY, state INTEGER NOT NULL, retry INTEGER DEFAULT 0, updated_at INTEGER);抓取前先占位,成功后置 2,失败 retry+1,超过 5 次进死信表;重启只捞 state=0/1 的记录,去重集合也从这张表来,不要放内存里的 set。第二,用 systemd 托管,别用 nohup 裸跑:[Service]ExecStart=/usr/bin/python3 /opt/crawler/main.pyRestart=alwaysRestartSec=5MemoryMax=2GOOMScoreAdjust=-200再配一个心跳文件:主循环每处理 100 条 touch 一次,外部脚本发现 mtime 超过 10 分钟就重启。WatchdogSec 也可以,但心跳文件更容易和业务进度对齐。第三,把资源上限写死:requests 全部 timeout=(5,20),Session 复用并 mount HTTPAdapter(pool_maxsize=64),响应体用 stream=True 边下边解析,日志用 RotatingFileHandler。每轮结束打印 processed/failed/queue_size/rss 四个数,rss 连续上升基本就是泄漏。最后提醒一句:如果断之前 CPU 和内存都正常、只是没有新日志,优先查“卡在某个 socket 读”而不是被限流;给 socket 设超时并加 SIGALRM 兜底,通常就能把“跑着跑着不动了”变成一条可重试的失败记录。
发布时间 2026/10/18 16:31:20 最后回复 yd_282022914 2026/10/23 14:01:02 版块 数据库
41 5 0