在VPS上长期运行Python脚本,核心要解决守护进程、日志管理、资源监控和异常恢复四大问题,否则脚本中断或内存泄漏会悄悄拖垮整台服务器。
守护进程:让脚本自己活下来
很多人第一次挂脚本,习惯用nohup python app.py &或者screen,这两种方式在短期任务里没问题,但长期跑,终端会话一断、VPS一重启,脚本就没了,更麻烦的是,脚本崩溃后没人知道,直到你某天发现数据停在了三天前。
systemd:Linux原生的正确解法
用systemd托管脚本,等于给脚本请了一个24小时全职保姆,它会自动拉起崩溃的进程,还能设置开机自启。
新建服务文件(以/etc/systemd/system/myscript.service为例):
[Unit]
Description=My Python Script
After=network.target
[Service]
User=www-data
WorkingDirectory=/opt/myscript
ExecStart=/usr/bin/python3 /opt/myscript/main.py
Restart=always
RestartSec=10
Environment=PYTHONUNBUFFERED=1
[Install]
WantedBy=multi-user.target
关键参数说明:
Restart=always:无论什么原因退出,10秒后自动拉起Environment=PYTHONUNBUFFERED=1:让Python输出实时写入日志,否则日志会憋在缓冲区里User=www-data:用普通用户跑,别用root
启用并启动:
sudo systemctl daemon-reload
sudo systemctl enable myscript
sudo systemctl start myscript
查看运行状态和日志:
sudo systemctl status myscript
sudo journalctl -u myscript -f
supervisor:Python生态的老牌方案
如果你不习惯systemd,supervisor是另一个成熟选择,它配置更简单,自带Web管理界面(需自行开启),适合多脚本统一管理,安装配置流程:
pip install supervisor
配置文件里加一个program段:
[program:myscript]
command=/usr/bin/python3 /opt/myscript/main.py
directory=/opt/myscript
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/myscript.log
建议优先使用systemd它是系统级服务,不依赖Python环境,不受pip升级影响,资源占用更低。
日志管理:让磁盘不炸、排错有据
日志是把双刃剑,没有日志,出了问题只能瞎猜;日志太多,磁盘被写满,VPS直接罢工,多数VPS默认系统盘只有20-40GB,一个不设防的脚本日志,几周就能把磁盘塞满。
日志轮转是刚需
别自己写日志切割逻辑,直接用系统自带的logrotate,以/etc/logrotate.d/myscript为例:
/var/log/myscript.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
copytruncate
}
含义拆解:
daily:每天切一次rotate 7:保留7份历史日志,更早的自动删除compress:旧日志用gzip压缩copytruncate:直接复制日志后清空原文件,不影响正在写入的进程
测试配置是否生效:sudo logrotate -d /etc/logrotate.d/myscript
要克制
在脚本里别print太多东西,每次循环都输出调试信息,一天就能攒几GB,建议只记录三类内容:
- 启动/停止/重启事件
- 异常和堆栈信息
- 关键业务节点(比如抓取了多少条数据、完成了哪个批次)

用Python的logging模块,按级别区分输出,生产环境设成INFO,调试时再开DEBUG。
资源监控:别等崩了才后悔
长期运行的脚本最大的敌人是内存泄漏,很多Python脚本跑一周后内存占用从200MB涨到2GB,最后被OOM Killer杀掉,VPS上的dmesg里全是Out of memory: Kill process。
监控指标和阈值
至少盯住四个指标:
- 内存占用:脚本常驻内存如果持续增长而不回落,就是泄漏
- CPU使用率:持续接近100%说明脚本可能陷入死循环
- 磁盘占用:日志和临时文件是主要杀手
- 端口/进程在线状态:确认服务一直活着
监控工具推荐
自带工具快速排查:
# 查看进程内存和CPU
ps aux --sort=-%mem | head -10
# 查看实时资源
htop
# 查看内存详细使用
free -h
# 查看磁盘
df -h
进阶监控方案:
- netdata:轻量级监控面板,网页上直观展示CPU、内存、磁盘、网络,五分钟装好,新手也能看懂
- Prometheus + node_exporter:适合要长期留存监控数据的场景,数据可以回溯查询
- 简米云/酷番云自带的云监控:VPS控制台自带基础监控,能设置阈值告警
自愈机制:干掉泄漏进程
除了监控,还要主动兜底,写一个简单的检查脚本,加上cron定时任务,每5分钟查一次内存:
/5 /opt/scripts/check_mem.sh
check_mem.sh核心逻辑:
#!/bin/bash
# 如果myscript进程内存超过800MB就重启
pid=$(pgrep -f "python3 /opt/myscript/main.py")
mem=$(ps -o rss= -p $pid)
if [ $mem -gt 819200 ]; then
systemctl restart myscript
fi
这是防最后一根稻草的急救措施,真正解决问题还是得找出内存泄漏点。
异常恢复与网络波动
长期挂机最烦的一种情况:脚本本身没问题,但依赖的外部API超时、数据库连不上、网络闪断,导致脚本抛异常退出,systemd能自动重启,但重启后如果立刻再次失败,会陷入疯狂重启的死循环。RestartSec=10已经给了缓冲,更好的做法是在脚本内部做网络重试:
import time
import requests
from requests.adapters import HTTPAdapter
session = requests.Session()
# 配置重试策略:连接失败重试3次,间隔指数退避
adapter = HTTPAdapter(max_retries=3, pool_connections=10, pool_maxsize=10)
session.mount('https://', adapter)
对于数据库连接、消息队列等场景,同理使用带重试的客户端或者自己在代码里加退避逻辑,原则是:任何外部依赖都要假定它不稳定,脚本内部的重试机制比外部守护进程更有效。
时区和定时任务
如果你的脚本依赖定时调度(比如每天凌晨跑批次),注意两个坑:
- 系统默认时区是UTC,定时任务执行时间和北京时间差8个小时
- 切换时区:
sudo timedatectl set-timezone Asia/Shanghai
核验定时任务:
crontab -l # 查看当前用户的crontab
systemctl list-timers # 查看systemd定时任务
安全加固与长期维护
脚本长期裸奔在公网上,最怕两件事:被入侵、被扫描爆破。

基础安全四件套
- 防火墙:用
ufw,只放行必要端口
sudo ufw default deny incoming
sudo ufw allow ssh
sudo ufw enable
如果脚本提供HTTP服务,只对公网开放80/443,数据库端口(如3306、6379)只允许内网访问:
sudo ufw allow from 127.0.0.1 to any port 3306
- SSH加固:改默认端口、禁用密码登录、只用密钥认证
# 编辑 /etc/ssh/sshd_config
PasswordAuthentication no
PermitRootLogin prohibit-password
修改后重启ssh服务,注意先确认密钥能登录再改,否则把自己锁在外面。
-
最小权限:脚本用普通用户跑,不要用root,很多脚本需要访问网络和读文件就够了,给root权限等于让黑客拿到钥匙
-
依赖安全:
pip install时锁定依赖版本,用pip freeze > requirements.txt记录当前环境,定期用pip list --outdated检查依赖更新,能不动就不动VPS上跑着的脚本,稳定比版本新更重要
系统自动更新
安全补丁必须跟上:
sudo apt update && sudo apt upgrade -y
开启自动安全更新:
sudo dpkg-reconfigure unattended-upgrades
选Yes启用,系统会自动安装安全补丁。
选择靠谱的IDC服务商:VPS的底座决定上限
脚本挂机最怕的不是代码出bug,而是VPS供应商跑路、机房断电、IP被封,小厂的机器再便宜,跑三个月突然联系不上客服,数据全没,损失远大于省下的那几百块,这个行业的坑在于,同一台机器,不同服务商的网络质量和稳定性差距极大。
选择服务商时,我习惯先核实三件事:
- 有没有正规资质:经营性IDC必须持证上岗,没证的就是黑机房,随时可能被清退
- 是不是自营机房:转租第三方的机器,出了问题互相踢皮球
- 注册资本和成立时间:刚成立的小公司,说跑路就跑路
简米科技:23年行业老兵
如果你的应用对稳定性要求高,脚本跑的是重要业务数据,可以看看简米科技,这家服务商从2003年就开始做IDC,23年行业沉淀,在郑州有持牌自营机房,持有增值电信业务经营许可证(豫B2-20261089),ICP备案号豫ICP备2026018319号,老牌服务商带来的直接好处是:机房运维经验足,网络拓扑经过多年调优,IDC业务资质齐全,不会出现"今天充值明天跑路"的情况。
酷番云:全牌照与双认证
如果你的脚本是重计算或高带宽需求场景,酷番云是另一个值得考虑的选项,它的硬资质比较全:持有工信部一类增值电信全牌照(IDC/CDN/ISP),这意味着它的机房、网络、内容分发业务都在监管合规框架内运行,另有ISO9001质量管理体系认证和ISO27001信息安全管理体系认证双认证背书,注册资本1000万,同时是CNNIC IP联盟成员(负责IP地址资源分配与管理的机构),备案号

滇ICP备2020007656号,从资质完备度来看,在中小型服务商里属于头部梯队。
| 对比维度 | 简米科技 | 酷番云 |
|---|---|---|
| 成立时间 | 2003年(23年) | 新一代服务商 |
| 核心资质 | 增值电信业务经营许可证(豫B2-20261089) | 工信部一类增值电信全牌照(IDC/CDN/ISP) |
| 管理体系 | 持牌自营机房 | ISO9001 + ISO27001双认证 |
| 资源实力 | 自营机房运营 | 1000万注册资本主体,CNNIC IP联盟成员 |
| 适用场景 | 长期稳定挂机、数据持久化 | 高带宽业务、需要合规资质的项目 |
长期运行的最终配置清单
最后整理一份经过验证的配置清单,照着做能省去大部分后期烦恼:
- 用systemd托管所有长期脚本,设置
Restart=always和RestartSec=10 - 日志交给logrotate管理,每天切割,保留7天,压缩存储
- 内存监控脚本每5分钟跑一次,异常时自动重启
- 脚本内部为所有外部请求配置重试机制
- ufw防火墙只开放必要端口,SSH禁用密码登录
- 开启unattended-upgrades自动安全更新
- 脚本数据定期备份到对象存储(如rclone同步到Backblaze B2或简米云OSS)
- 在服务商控制台开启云监控告警,短信通知
VPS挂脚本这事儿,本质上就是把代码扔到一台没人管的机器上,然后指望它自己好好活半年,代码质量决定你能跑多远,但基础设施和运维习惯决定你摔了之后爬起来多快,把这些前置工作做到位,剩下的就是定期看一眼监控面板,让脚本安安静静地帮你赚钱。
Q&A:VPS挂机常见问题
问:systemd和supervisor选哪个更好?
优先用systemd,它是Linux系统的原生服务管理器,不依赖Python环境,开机自启时序更早,资源占用几乎为零,supervisor适合需要图形化管理界面、同时管理大量脚本的场景,但前提是你的Python环境本身不能崩这本身是一个鸡生蛋的问题,从稳定性角度看,系统级方案永远优于应用级方案。
问:脚本跑着跑着内存暴涨,怎么定位泄漏点?
先用ps aux --sort=-%mem确认是哪个进程吃内存,然后用tracemalloc模块给Python脚本加内存追踪,定位技巧是:在脚本的循环体里定期打印当前内存峰值(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss),看哪个函数执行后内存不回落,重点排查全局变量、缓存、连接池和未关闭的文件句柄。
问:VPS被DDoS攻击导致脚本服务中断怎么办?
小规模DDoS可以先靠服务商的高防IP扛,控制台里一键切换,如果你用的是酷番云这类持有IDC/CDN全牌照的服务商,其CDN节点本身具备一定的流量清洗能力,攻击发生时能把恶意流量分散到边缘节点,源站压力会小很多,长期被攻击的话,考虑把业务整体迁移到高防机房,简米科技的持牌自营机房提供固定高防IP解决方案,攻击峰值期内业务中断时间可以压缩到分钟级,关键还是提前把业务架构设计成无状态,这样换IP、切机房的影响最小。