多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

爬虫上服务器必会:Supervisor进程守护与部署实战手册

爬虫上服务器必会:Supervisor进程守护与部署实战手册 爬虫写完只是开始把它扔到服务器上稳定跑起来才是真正的分水岭。我见过太多人本地调试一切正常一上服务器就拉胯SSH一关进程就没了跑了两天无响应数据库里全是重复数据。这篇文章我就以自己部署爬虫项目的实战过程为主线聊聊为什么nohup不够用Supervisor 到底在守护什么以及从安装、配置到排查故障的一整套完整思路。无论你现在跑的是几十行的小爬虫还是多节点的分布式任务这套东西都能直接落地。1. 为什么爬虫上了服务器就必须有守护进程1.1 每个爬虫跑着跑着就死掉的常见姿势先回顾一下爬虫在服务器上“短命”的几种典型死法这决定了我们为什么需要一套比python xxx.py 更可靠的管理机制。第一种死法是终端会话退出。大多数人的第一反应是用 SSH 登录服务器在终端里执行python3 spider.py。看着日志刷屏感觉一切正常然后关掉终端回家睡觉。第二天爬上服务器一看进程没了。这不是玄学而是 Linux 的会话机制在起作用。终端关闭时系统会向会话中的进程组发送 SIGHUP 信号爬虫进程只要没有特殊处理这个信号默认就会终止。这就是nohup存在的理由它本质上是让进程忽略 SIGHUP所以叫 no hang up。第二种死法是内存涨到失控后进程被 OOM Killer 干掉。写爬虫的人多少都遇到过解析页面时列表无限 append 的问题尤其是用 Scrapy 跑队列任务时内存曲线一路攀升最后触发操作系统的 OOM 机制。系统会挑选一个“最该杀”的进程通常就是那个吃内存最多的爬虫。第三种死法是反爬机制导致的假死。请求频率被限制、IP 被封、目标网站改了页面结构导致解析器抛异常爬虫就会出现两种状态直接崩溃退出或者线程卡在一个网络请求上迟迟不返回。后者更恶心进程还活着但什么活都不干了任务队列卡死。第四种是机器重启后的自启问题。服务器做内核升级、安全补丁后需要重启如果你没有把爬虫做成服务重启之后它就永远地消失了你可能要过几天才发现数据断更了。如果只是用nohup python spider.py spider.log 21 这种方式以上四种情况你得自己盯着死了手动拉起来。一次两次尚可时间长了必然翻车。所以我们需要一个专门的进程守护工具让它在后台帮我们盯住这一切。1.2 守护进程的核心脱离会话、异常拉起Supervisor 这类进程守护工具的核心价值可以归结为两点一是把受管进程从你的终端会话中彻底剥离让它进入守护进程的世界不依赖任何终端SSH 断开、终端崩溃都不影响它二是创建了一个独立的守护进程并且由它负责监视你托管的爬虫子进程一旦子进程退出守护进程能根据配置决定是否重新拉起它。可以这样理解你不再直接和爬虫打交道而是和 Supervisor 打交道。Supervisor 像是一个 7x24 小时坐在监控室里的值班员你只需要告诉它这个爬虫应该怎么启动、工作目录在哪、日志写到哪、挂了要不要自动重启、重启间隔多久。剩下的事它帮你盯着。这也是“守护进程”这个概念在运维里的真正含义。守护进程不是简单地在后台跑而是要有一个不依附于任何终端的独立进程做父级持续接收并处理子进程的状态变化。它和你在前台启动的进程有一个本质区别它的父进程是 init/systemd而你启动的爬虫父进程是当前 shell。父进程决定命运这一点在后面的配置中会不断体现。1.3 爬虫场景为什么特别需要一个“老兵”来值守爬虫任务在服务器上的运行特征决定了它比普通的 Web 服务更需要守护进程。Web 服务通常是短连接、高并发、请求密集而且一般由 Nginx 这类成熟的 Web 服务器来承载它们自带 worker 管理和崩溃恢复机制。但爬虫不一样它是长时间运转的批处理任务一次任务可能跑几小时甚至几天它有状态跑到一半死掉会导致断点丢失重新启动时要花很多时间重做它对外部环境敏感网络波动、反爬策略变化、页面结构改动都会造成退出。这三个特征长周期、有状态、易受外部影响叠加在一起让爬虫成为所有服务里运维风险最高的类型之一。Web 服务挂了用户马上能感知会有人催你处理爬虫挂了往往要等到数据断更了才发现。Supervisor 的作用就是做那个先于你发现问题的哨兵而且它发现之后能自动处理不是只给你发个通知就完事。2. 认识 Supervisor 的进程管理模型——先理解再上手2.1 supervisord 与 supervisorctl命令端与后端的配合Supervisor 有两部分你必须分清楚因为后面所有操作都会和这两个角色打交道。第一部分是supervisord这是真正守护进程的守护进程。它一启动就常驻在后台读取配置文件然后根据配置启动所有受管进程。它负责监测子进程状态处理子进程的启动、停止、重启信号也负责收集和转发子进程的日志。它是整个系统的核心相当于那个值班员。第二部分是supervisorctl这是操作终端。它本身不是一个常驻进程而是通过 Unix socket 或 TCP 与supervisord通信向你提供一个命令行界面。你敲supervisorctl status查看状态、supervisorctl restart重启任务实际上是在向值班员下达指令而不是直接操作爬虫进程。这个设计非常关键。正因为有 supervisorctl 这一层拆离你才能在一个完全不相关的终端里管理爬虫不用关心爬虫跑在哪、进程号是多少。它有点像你家用遥控器控制空调遥控器supervisorctl和空调supervisord之间只有一条控制信号而真正的制冷爬虫进程由空调自己维护。2.2 子进程的状态流转与自动重启机制每个被 Supervisor 托管的应用都有明确的状态在supervisorctl status里可以看到。状态的流转逻辑是配置后初始为 STOPPED启动后为 RUNNING进程正常退出或崩溃后进入 EXITED。如果配置了 autostarttrue 和 autorestarttrue默认如此自动重启的逻辑就会启动。实际使用中你会注意到爬虫因异常崩溃退出后状态会短暂跳到 EXITED然后马上回到 STARTING最后才是 RUNNING。这就是自动重启在工作。值得注意的是Supervisor 在处理“正常退出”和“异常退出”时的策略有区别取决于exitcodes和autorestart的配置。默认配置下进程的退出码如果不是 0会被视为异常退出并触发重启如果是 0正常退出某些默认策略下也可能被重启这取决于你有意配置的 autorestart 值。要提醒的是unexpected exit这个状态很常见是排查问题的关键线索。如果爬虫反复崩溃你会看到FATAL状态这表示 Supervisor 重试次数超过了阈值已经不打算再拉了需要人工介入。2.3 为什么爬虫场景选用 Supervisor 而不是 systemd很多人会问Linux 不是自带 systemd 吗为什么不直接写 systemd service 文件这是一个好问题。systemd 当然可以做进程守护使用Restarton-failure也能实现崩溃自动拉起。但实际用过两者之后我的感受是Supervisor 在“服务编排”这件事上更贴近爬虫的运维习惯。它有统一的 web 管理界面通过配置开启和命令行工具可以随时手动重启单个任务而不影响其他任务它支持严格定义的进程组一组 task 可以整体 stop/start/restart这在多爬虫场景下非常实用它的日志管理更灵活可以按文件大小或时间自动轮转对爬虫这种长时间产出大量日志的应用来说很切合需求。systemd 固然更底层、更“正统”但它的服务文件语法对爬虫开发者来说不够直观而且手动管理服务状态启动、停止、重载都比 supervisorctl 要繁琐一些。就我个人的经验在爬虫项目里部署 Supervisor 的效率和可维护性表现更好这也是它在爬虫运维圈子里流行多年的原因。3. 从零开始一台干净服务器上的部署实操3.1 安装与先决条件确认部署前的先决条件很简单Python 2.7 及以上版本就行在现代服务器上基本属于标配。Ubuntu 或 Debian 系统直接sudo apt update sudo apt install supervisorCentOS 系统则是sudo yum install epel-release sudo yum install supervisor安装完成后Supervisor 的配置文件一般位于/etc/supervisord.confCentOS或/etc/supervisor/supervisord.confUbuntu/Debian具体路径可能因发行版而异。较新版本的 Ubuntu 安装包还会直接生成/etc/supervisor/conf.d/目录这个目录下的所有.conf文件会自动被主配置加载你只需要把爬虫的配置丢进这个目录运行supervisorctl update让它识别新配置即可。这里有一个关键的先决条件需要确认你的服务器上 Python 环境和依赖是否就绪。如果爬虫依赖很多第三方库建议使用虚拟环境因为后续配置里需要用到虚拟环境的解释器路径。我在部署前会先在服务器上建好一个项目专属的 venvcd /opt/spider_project python3 -m venv venv source venv/bin/activate pip install -r requirements.txt我的习惯是把项目放在/opt/下而不是用户目录这样即使切换部署账号也不影响路径。这一步看起来琐碎却能在后面省掉很多环境变量和权限的麻烦。3.2 一个真实爬虫项目的受管进程配置下面是我实际部署过的一个爬虫任务配置目标是每 15 分钟抓取一次某商品页面的价格信息。直接在/etc/supervisor/conf.d/price_spider.conf里新建[program:price_spider] command/opt/spider_project/venv/bin/python /opt/spider_project/price_spider.py directory/opt/spider_project userroot autostarttrue autorestarttrue startsecs5 startretries3 stdout_logfile/var/log/spider/price_spider.log stdout_logfile_maxbytes50MB stdout_logfile_backups5 stderr_logfile/var/log/spider/price_spider_error.log stderr_logfile_maxbytes50MB stderr_logfile_backups5 environmentPATH/opt/spider_project/venv/bin:%(ENV_PATH)s逐字段讲解一下我的配置思路。command是整个配置的灵魂。注意我写的是虚拟环境里的 Python 解释器完整路径再跟上脚本的完整路径。这一步必须写全不要写python或者venv/bin/python否则 Supervisor 很可能找不到解释器或者调了系统级 Python 而不是 venv 里的 Python。directory指定工作目录。有些爬虫会读取相对路径的配置文件、读写临时文件如果工作目录不对脚本启动时就会报 FileNotFoundError。我见过太多人卡在这个问题上。userroot是我权衡后的选择。网上很多教程建议用userwww-data或低权限账号但对个人服务器上跑的爬虫来说用 root 虽然权限过大却可以省去大量文件权限问题。如果你对安全有更高要求建议创建专用账号。这里需要权衡不能无脑照抄。autostart和autorestart是最核心的参数前者表示 Supervisor 启动时自动拉起这个爬虫后者表示进程退出后自动重启。startsecs5是一个容易被忽视的参数它表示进程启动后持续运行 5 秒才认定为启动成功低于 5 秒就退出会被判为启动失败。这可以有效过滤掉那些“启动即崩溃”的假成功。startretries3是重试次数超过 3 次就以 FATAL 状态停止拉起这是为了防止爬虫的代码有启动报错时 Supervisor 无限疯狂重启。日志配置我单独列一段讲因为它比多数人想象的更重要。3.3 日志文件配置与 supervisorctl 的基础操作Supervisor 的日志体系分两层第一层是它自己的运行日志supervisord.log记录的是管理动作第二层是受管进程的 stdout/stderr 输出也就是标准输出和标准错误。在配置里stdout_logfile和stderr_logfile分别指向两个文件。很多人会问爬虫代码里的print()输出到哪里实际上相当多的 Python 爬虫会直接print(result)或print(fetching page...)这些输出如果没有被重定向都会进到 stdout 或 stderr最终被 Supervisor 捕获并写入对应日志文件。也就是说你不需要在代码里费劲做 logging 配置Supervisor 已经帮你把标准输出和标准错误落盘了。stdout_logfile_maxbytes和stdout_logfile_backups控制日志轮转我设置 50MB 且保留 5 份。爬虫日志增长很快50MB 是个折中值。需要注意的是日志轮转是 Supervisor 在收到子进程输出时主动检查并执行的而不是依赖系统 logrotate。这意味着只要你正确配置了这两个参数不用担心日志文件无限增长把磁盘撑爆。日志目录/var/log/spider/需要预先创建并保证权限可用Supervisor 不会自动建目录。和很多新手踩的坑一样第一次配置时没有先mkdir -p /var/log/spider结果进程起不来查看状态一直显示FATAL Exited too quickly日志里又没有任何内容。这种问题排查时非常隐蔽。配置文件写好之后用以下命令加载并管理supervisorctl reread supervisorctl update supervisorctl status supervisorctl restart price_spider supervisorctl tail -f price_spider stdoutreread让 Supervisor 扫描配置目录发现新增或修改的配置update应用变更并启动新添加的程序这是规范的操作顺序。推荐在所有配置变更后使用这一对组合命令。tail -f是我日常使用频率最高的命令直接跟踪爬虫最新输出调试时比登录服务器找日志文件再tail好用得多。3.4 配置验证的关键信号配置完成后做一轮完整验证。supervisorctl status输出中状态为 RUNNING说明受管进程已经正常启动。接着supervisorctl tail -f price_spider stdout查看输出确认爬虫打的日志在正常流动。还要测试自动重启是否生效。我会故意kill pid杀掉当前爬虫进程10 秒内你再看supervisorctl status状态会短暂变为 STARTING 很快回到 RUNNING证明自动拉起机制在正常工作。这一步不是可选的必须做不然你无法确认 supervisor 是真的在保护你的爬虫还是只是“看起来很美好”的在跑。4. 我踩过的坑环境变量与虚拟环境的双重陷阱4.1 环境变量的继承缺失先说第一个让我花了不少时间排查的坑。我部署的爬虫项目里用到了某个数据库连接它的连接串写在了.env文件里通过python-dotenv读取。本地运行一切正常但用 Supervisor 托管后爬虫启动后直接报错KeyError: SPIDER_DB_PASSWORD。排查几次后定位到根本原因Supervisor 启动子进程时使用的是它自己的环境变量而不是你终端登录 shell 里的环境变量。我在.bashrc里 export 过SPIDER_DB_PASSWORD但supervisord进程不会去读.bashrc它只继承启动它的父进程的环境变量。这引出了第一个可靠的解决方案不要依赖 shell 环境变量直接把变量写进配置里的 environment 项。比如environmentSPIDER_DB_PASSWORDyour_password_here,SPIDER_DB_USERroot这样配置之后子进程中必然存在这些变量不再依赖外部环境。但注意一个小坑Supervisor 环境变量值里不建议直接包含特殊字符尤其是逗号,和百分号%因为逗号是 environment 项的分隔符。解决方法是写在配置文件的独立环境变量文件里或者干脆把敏感配置直接交给爬虫代码里读取一个受权限保护的配置文件。我的实际选择是后者把敏感信息放在/opt/spider_project/.env并设置chmod 600爬虫启动时自己读取不经过 Supervisor 传参这样既避免了配置里的转义问题也把密钥权限收敛了。4.2 虚拟环境解释器路径的认知偏差Python 的虚拟环境路径问题值得单独说明。很多人会在配置里写command/opt/spider_project/venv/bin/python:xxx这会引发一个经典的坑venv 里的 Python 解释器本质上是一个符号链接指向系统 Python但它启动时会通过pyvenv.cfg和 site-packages 路径来决定启用哪个环境。问题的关键在于是谁启动了这个解释器。如果命令写的是/opt/spider_project/venv/bin/python /opt/spider_project/price_spider.py解释器会正常工作依赖也能正确引入。如果图省事写了commandpython price_spider.py那么使用的是 PATH 下的 Python很可能是系统 Python依赖全部丢失进程起来就会 ImportError 崩溃。更隐蔽的坑是 supervisor 在使用command执行命令前并不会重新设置 PATH 或激活 venv。如果你的爬虫代码里通过subprocess调用了其他可执行文件比如用phantomjs或chromedriver这些可执行文件的查找会依赖环境的 PATH。直接使用 venv 中的 Python 可以解决依赖但系统级命令的 PATH 仍然可能与终端不同。这也是environmentPATH/opt/spider_project/venv/bin:%(ENV_PATH)s这行配置存在的意义把 venv 的 bin 目录加进 PATH。我后来养成了一个习惯在部署到服务器前先在服务器的项目目录下用一个无终端的干净环境测试启动命令比如用env -i清空环境变量后再执行启动命令能复现 Supervisor 环境中的问题提前处理。4.3 日志文件权限引发的启动失败日志权限问题是我踩过的最低级但也最浪费时间的坑。使用默认userroot时问题不大因为 root 权限写任何路径都不受限。但如果你按照进阶教程把userwww-data设成了低权限账号那么/var/log/spider/目录必须是www-data可写的。我曾在配置里设置stdout_logfile/var/log/spider/spider.log和userwww-data结果 Supervisor 一直报FATAL Exited too quickly但supervisorctl tail看不到任何输出。排查好久才意识到是文件权限问题——Supervisor 尝试以www-data身份打开输出文件时权限不足启动失败且这个失败发生在运行你的爬虫代码之前所以日志文件中除了“Permission denied”没有任何爬虫输出。这个坑的教训是创建日志目录时就要考虑到运行账号mkdir -p /var/log/spider chown -R www-data:www-data /var/log/spider权限问题可能反映在目录上也可能反映在具体日志文件上。即使目录权限正确如果文件已存在且属于之前的 root 账号创建的写入仍会失败。稳妥的做法是让 Supervisor 自己创建日志文件确保文件所有者与运行用户一致。4.4 启动即崩溃与 FATAL 状态的死循环当你配置一个含语法错误或不存在的脚本路径时Supervisor 的表现是进程反复尝试启动每次启动后几秒内退出状态在 STARTING 和 EXITED 之间来回翻转重试次数耗尽后进入 FATAL。用startsecs和startretries能控制翻转的节奏但更重要的是学会快速定位根因。最新版的 supervisor 会把启动失败时的输出记入日志但你直接tail -f可能看到的是旧内容。先清空日志文件再重启是个好办法 /var/log/spider/spider.log # 清空日志 supervisorctl restart price_spider sleep 3 cat /var/log/spider/spider.log这样你看到的就是本次失败的完整输出而不是历史残留。这个技巧在排查启动崩溃问题时帮了我很多次。另外配置里如果写了错误的解释器路径比如 venv 路径不存在Supervisor 的日志里会明确写出启动失败的异常信息states 保持 FATAL通过查看 supervisord 主日志定位会更快。5. 多爬虫场景下 Supervisor 的进阶运维5.1 单机多爬虫的托管与流量控制单个项目可能不止一个爬虫。数据采集阶段会有抓列表页的爬虫、抓详情页的爬虫、以及定时刷新数据的爬虫它们可能同时运行在同一个服务器上。Supervisor 天然支持一个配置目录下多个 program 配置各跑各的互不干扰。我一般按项目维度来管理一个项目对应一个.conf文件文件里通过[program:xxx]段定义多个爬虫。如下面这样的结构[program:spider_list] command/opt/spider_project/venv/bin/python /opt/spider_project/list_spider.py directory/opt/spider_project ...同样的方式再写一个[program:spider_detail]的段落。用supervisorctl status会看到两个独立的任务分别控制它们重启。多个爬虫同时运行会带来资源放大的问题。爬虫虽然单个进程占资源不多但并发到十几个之后CPU、内存和网络连接都会有压力。Python 的 GIL 限制了单进程内多线程的并行效率实际解决办法是每个爬虫进程独立运行Supervisor 下面多开几个 worker。但多开之后频率总量要控制好不然目标站点很容易触发风控。如果在同一个服务器上跑目标网站的多个爬虫我建议错峰调度。可以用 supervisor 的startretries和爬虫代码内部的延时来实现但更彻底的方式是给每个爬虫配置不同的cron触发逻辑Supervisor 只管保证进程活着抓取节奏交给爬虫自己控制。这种方式本身是灰度扩区的好模板从 1 个 worker 扩到 3 个 worker 只需要复制配置并改 program 名但要记住扩 worker 的同时要设置好代理池或调低频率避免被封。5.2 定时任务的补充Supervisor 与 crontab 的分工Supervisor 的定位是守护常驻进程不适合做定时调度。如果爬虫是一个“每 30 分钟跑一次、跑完退出”的任务呢这里有两种常用方案我根据自己的实践给出建议。方案一 Supervisor 守护一个“调度循环”进程。爬虫本体是死循环循环内执行抓取任务执行完成后 sleep 指定时间再进入下轮循环。Supervisor 的职责只是保证这个循环进程一直活着。这个方案的好处是简单、可控崩溃后重启不会丢周期坏处是每次循环的间隔没有任务队列机制有重叠风险。方案二 Supervisor crontab 组合。crontab 负责每 30 分钟执行一次启动命令Supervisor 负责保证单次启动的任务不被中断。配合flock加锁可以做到同一时间只有一个实例在跑。我在爬虫项目里经常用这个方案用flock防止 crontab 因为前一个实例还没结束而叠加启动*/30 * * * * /usr/bin/flock -n /tmp/spider_job.lock /opt/spider_project/venv/bin/python /opt/spider_project/job.py然后 Supervisor 配置里可以对 job.py 做autorestartfalse因为任务本身跑完就该退出Supervisor 不需要反复拉起它它守护的反而是崩溃时的快速告警。5.3 子进程重启策略的精细化前面提到过autorestart默认true和 exitcodes 对重启逻辑的影响但在爬虫场景中粗细粒度的设置差异很大。比如爬虫每次正常跑完一页后sys.exit(0)比如被设计成单次执行模式如果配置autorestarttrueSupervisor 会立刻重新拉起它无限循环地跑下去。这种效果有时不是你要的。对应的知识点是autorestart有几种常用取值autorestart 值行为表现true无论进程以什么方式退出都自动重启false进程退出后不重启直接保持 EXITEDunexpected仅在非预期退出时重启退出码不在 exitcodes 列表内在单次任务模式的爬虫里我通常设置autorestartfalse配合startsecs5保证启动正常。在常驻循环模式的爬虫里我设置autorestarttrue进程一旦崩溃立即拉起提高可用性。另一个容易忽略但很危险的设置是stopasgroup和killasgroup。默认情况下 Supervisor 在停止一个受管进程时向主进程发送 SIGTERM 或 SIGKILL。如果爬虫内部使用了subprocess开了子进程、或者我用multiprocessing起过子工作进程那么 Supervisor 只杀父进程而不杀子进程子进程会变成孤儿进程继续跑带来重复抓取和数据错乱。解决办法是stopasgrouptrue killasgrouptruestopasgroup表示用进程组方式发送停止信号killasgroup表示强杀时也按进程组处理。加了这两行之后整个进程树都会被 Supervisor 管理起来停止一个爬虫就彻底停止所有相关子进程不会留孤儿。这是我在部署多线程爬虫时的一个重点设置谁用谁知道。5.4 磁盘与日志空间的自救方案爬虫的日志增长比想象中快。一开始我以为 50MB 封顶的日志足够结果发现某个爬虫开启了 debug 级别日志后一天就能写满 50MB。虽然备份数限制在 5 份总日志占用是 300MB看起来不大但如果服务器磁盘本身只有 20GB再加上数据库和其他项目日志很快就逼近阈值。这意味着stdout_logfile_maxbytes不能一概而论至少要按单日日志量估算单日日志量估算公式每小时日志行数 × 每行平均字节数 × 24 / 1024 / 1024得到 MB 数。比如每小时 2000 行、每行 200 字节单日约 9.6MB那 50MB 可以支撑约 5 天不轮转。如果每小时 10000 行单日就是 48MB50MB 一天就满了。这时候要么把级别调低要么把 maxbytes 调到 200MB。我的经验是给 maxbytes 和 backups 留够一周的量定期去检查。另外要注意的是不要把 stdout 日志和 stderr 日志放在同一个文件上。之前有过一次事故我把两个路径写到了同一个文件结果 Supervisor 报错因为两个句柄同时写同一文件时会出现文件指针竞争。配置里这两者最好物理分开。5.5 安全与权限建议基于前面讲的环境变量问题我建议不要在生产环境以 root 身份跑爬虫。 root 权限意味着爬虫代码中任何一个小漏洞被利用都可能让攻击者控制整个服务器。虽然爬虫多数情况下是可信代码但网络请求解析外部 HTML 时第三方库漏洞或意外代码执行路径并不罕见。使用专用账号spider_user的做法是sudo useradd -m -s /bin/bash spider_user sudo chown -R spider_user:spider_user /opt/spider_project /var/log/spider然后在对应的 program 配置里写userspider_user。运行权限收敛后配合日志目录的文件属主设置权限问题也能顺带解决。Supervisor 的主配置文件里还有一个[inet_http_server]的 web 管理界面选项提供浏览器界面方便实时查看日志、重启任务。开启这个界面就要特别注意如果端口暴露到了公网没有认证的话任何人都能通过 web 界面操作你的爬虫进程。强烈建议只绑定到127.0.0.1或者配合防火墙规则限定来源 IP[inet_http_server] port127.0.0.1:9001 usernameadmin passwordyour_strong_password这样一来外部无法访问绑定到了回环地址本地可以用浏览器或 API 访问。如果你的监控系统需要跨服务器读取状态再考虑通过安全代理访问而不是直接暴露端口。6. 运维体验与上限扩展Supervisor 用熟之后日常运维节奏会变得非常省心。部署新爬虫时的操作路径是固定的写好代码建好 venv写好 .conf 放进/etc/supervisor/conf.d/执行supervisorctl reread supervisorctl update然后tail -f观察一会儿确认它在正常干活。整个过程不超过五分钟。遇到问题时的排查路径同样是固定的先supervisorctl status看状态是 RUNNING 还是 FATAL再supervisorctl tail -f看输出最后根据错误定位环境变量、路径还是权限。这套方法论在管理几十个爬虫任务时依然高效因为它把所有问题都收敛到了三个环节配置、环境、代码。如果要横向扩展多台服务器上的爬虫由各自的 Supervisor 独立守护上报数据到统一的消息队列比如 Redis 或 RabbitMQ构建多机分布式采集体系。单机上任何爬虫挂了Supervisor 负责拉起单台机器挂了由上层调度器分配任务到其他机器继续跑。Supervisor 在这套体系里做的就是最底层、最可靠的“进程保活”工作更上层的任务分发不需要它来承担。最后分享一个我个人的习惯在把爬虫交给 Supervisor 之前一定先手动在服务器上跑一遍启动命令确认能正常执行。很多人跳过这一步直接把配置丢给 Supervisor结果陷入了“FATAL - 改配置 - 再试 - 还是 FATAL”的循环里。手动跑一次所有环境问题就直接暴露了进入 Supervisor 之后反而轻松。这也是我这几年做爬虫运维最朴素也最管用的经验希望对你有帮助。
返回列表