From 7da799d4dbf43b57d296815854ca17c1187eebeb Mon Sep 17 00:00:00 2001 From: xxm Date: Wed, 5 Aug 2026 14:57:10 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20price=5Fmonitor=E8=87=AA=E6=84=88?= =?UTF-8?q?=E5=BC=8F=E5=8D=95=E4=BE=8B=E5=AE=88=E5=8D=AB(=E8=BF=9B?= =?UTF-8?q?=E7=A8=8B=E5=A0=86=E7=A7=AF=E4=BA=8B=E6=95=85)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - cron每2分钟拉起+外网抖动挂起+timeout仅SIGTERM杀不动 → 5并发烧155%CPU - 新鲜实例在跑则退出(防堆积); 卡死>300s则SIGKILL接管(自愈) - 符合进程生命周期铁律(防重复启动+卡死检测+自动清理) --- deploy/profile-scripts/price_monitor.py | 38 +++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/deploy/profile-scripts/price_monitor.py b/deploy/profile-scripts/price_monitor.py index 158b01fa..40c9b7ae 100644 --- a/deploy/profile-scripts/price_monitor.py +++ b/deploy/profile-scripts/price_monitor.py @@ -818,8 +818,46 @@ def run_once(round_label=""): pass +def _singleton_guard(max_age_sec=300): + """自愈式单例守卫(2026-08-05 进程堆积事故修复) + 背景:cron每2分钟拉起本脚本,外网抖动时实例挂起不退,timeout(仅SIGTERM)杀不动, + 5个并发烧~155% CPU。规则: + - 有其他"新鲜"实例(存活max_age)→ SIGKILL 接管(自愈) + """ + import subprocess as _sp, os as _os, sys as _sys + my_pid = _os.getpid() + try: + out = _sp.run(["ps", "-C", "python3", "-o", "pid,etimes,cmd"], + capture_output=True, text=True, timeout=10).stdout + for line in out.splitlines(): + if "price_monitor.py" not in line: + continue + parts = line.split(None, 2) + if len(parts) < 3: + continue + try: + pid = int(parts[0]); age = int(parts[1]) + except ValueError: + continue + if pid == my_pid: + continue + if age > max_age_sec: + try: + _os.kill(pid, 9) + print(f"[guard] SIGKILL卡死实例 pid={pid} age={age}s", flush=True) + except ProcessLookupError: + pass + else: + print(f"[guard] 已有新鲜实例 pid={pid} age={age}s 在跑, 本实例退出", flush=True) + _sys.exit(0) + except Exception as _e: + print(f"[guard] 守卫异常(放行): {_e}", flush=True) + + def main(): """每cron触发跑一轮""" + _singleton_guard(max_age_sec=300) run_once()