用户问「同一账号多久重检是啥意思」,顺着查发现**我的作业没在用它**。
## 「同一账号多久重检」是什么
**每个账号的体检周期**:一个账号这轮被查了,多久之后才重新进入候选。
批量扫描类作业的通用参数,配合另外两个决定"扫不扫得过来":
需要的能力 = 总账号数 ÷ 重检间隔
实际的能力 = 每轮条数 ÷ 运行间隔
**实际 < 需要 → 永远扫不完**(队列越来越长)。
按这个口径核对「CK 自动巡检」的默认值(生产 14,574 个持有 CK 的账号):
需要 14,574 ÷ 6 小时 = 2,429 个/小时
实际 200 条 ÷ 5 分钟 = 2,400 个/小时
**几乎精确匹配** —— 那两个默认值是校准过的,不用动。
## 但我的作业读的是 config 里的 refresh_days
于是界面上那个「同一账号多久重检」**对本作业是死的**(改了没反应)——
正是用户上一条批评过的同一类缺陷:「看起来能配、其实配的是不相干的东西」。
我在同一个问题上连着栽了两次(上一次是拿 `interval_seconds` 当调度频率算吞吐)。
改成 `job.interval_seconds`,与其它批量作业**同一套口径**;
默认 7 天(查过的账号 7 天后再查)。config 里的 `refresh_days` 整个去掉。
## 顺带
- 注册处显式写明两个参数:`interval_seconds=7 天`(重检)+ `run_interval_seconds=5 分钟`(调度)
- 用例改名并加注释,钉住"重检间隔必须来自界面那个字段"
## 验证
TZ=Asia/Shanghai **639 passed / 6 skipped**;ruff 全绿;前端 build 通过。
143 lines
4.9 KiB
Python
143 lines
4.9 KiB
Python
"""自动化调度:作业注册、调度线程与各作业实现。
|
||
|
||
登记作业请放在 ``register_default_jobs()``,由 ``main.py`` 在启动时调用一次,
|
||
避免 import 顺序影响注册结果。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from .jobs.account_overview_refresh import (
|
||
JOB_KEY as ACCOUNT_OVERVIEW_REFRESH_KEY,
|
||
)
|
||
from .jobs.account_overview_refresh import (
|
||
run_account_overview_refresh,
|
||
)
|
||
from .jobs.ck_health import JOB_KEY as CK_HEALTH_KEY
|
||
from .jobs.ck_health import run_ck_health
|
||
from .jobs.ck_relogin import JOB_KEY as CK_RELOGIN_KEY
|
||
from .jobs.ck_relogin import run_ck_relogin
|
||
from .jobs.douyu_tasks_retention import (
|
||
JOB_KEY as DOUYU_TASKS_RETENTION_KEY,
|
||
)
|
||
from .jobs.douyu_tasks_retention import (
|
||
run_douyu_tasks_retention,
|
||
)
|
||
from .jobs.points_expire import JOB_KEY as POINTS_EXPIRE_KEY
|
||
from .jobs.points_expire import run_points_expire_check
|
||
from .scheduler import (
|
||
JobSpec,
|
||
automation_enabled,
|
||
ensure_jobs,
|
||
register_job,
|
||
registered_jobs,
|
||
reset_registry,
|
||
run_due_jobs,
|
||
run_job_now,
|
||
scheduler_status,
|
||
start_scheduler,
|
||
stop_scheduler,
|
||
)
|
||
|
||
__all__ = [
|
||
"ACCOUNT_OVERVIEW_REFRESH_KEY",
|
||
"CK_HEALTH_KEY",
|
||
"CK_RELOGIN_KEY",
|
||
"DOUYU_TASKS_RETENTION_KEY",
|
||
"POINTS_EXPIRE_KEY",
|
||
"JobSpec",
|
||
"automation_enabled",
|
||
"ensure_jobs",
|
||
"register_default_jobs",
|
||
"register_job",
|
||
"registered_jobs",
|
||
"reset_registry",
|
||
"run_account_overview_refresh",
|
||
"run_ck_health",
|
||
"run_ck_relogin",
|
||
"run_douyu_tasks_retention",
|
||
"run_due_jobs",
|
||
"run_job_now",
|
||
"run_points_expire_check",
|
||
"scheduler_status",
|
||
"start_scheduler",
|
||
"stop_scheduler",
|
||
]
|
||
|
||
|
||
def register_default_jobs() -> None:
|
||
"""登记内置作业(幂等)。"""
|
||
register_job(
|
||
JobSpec(
|
||
key=POINTS_EXPIRE_KEY,
|
||
title="积分到期补记",
|
||
# 每天一次足够:到期时刻的精度是「天」级别,晚几小时记也不影响
|
||
interval_seconds=24 * 3600,
|
||
batch_size=200,
|
||
concurrency=1,
|
||
run=run_points_expire_check,
|
||
)
|
||
)
|
||
register_job(
|
||
JobSpec(
|
||
key=DOUYU_TASKS_RETENTION_KEY,
|
||
title="任务日志清理",
|
||
# 一天一次足够:这是**清理**,不是业务;跑太勤只是白扫索引。
|
||
interval_seconds=24 * 3600,
|
||
batch_size=2000,
|
||
concurrency=1,
|
||
run=run_douyu_tasks_retention,
|
||
)
|
||
)
|
||
register_job(
|
||
JobSpec(
|
||
key=CK_RELOGIN_KEY,
|
||
title="CK 自动重登",
|
||
# interval_seconds 同样是「同一行多久重试一次」的兜底(真实节奏由
|
||
# relogin_next_at 的退避表决定);批次小、跑得慢,单轮 10 条。
|
||
interval_seconds=6 * 3600,
|
||
batch_size=10,
|
||
concurrency=3,
|
||
run=run_ck_relogin,
|
||
)
|
||
)
|
||
register_job(
|
||
JobSpec(
|
||
key=ACCOUNT_OVERVIEW_REFRESH_KEY,
|
||
title="账号资料定时补全",
|
||
# 每 10 分钟一轮、每轮 400 个。
|
||
#
|
||
# 依据是**试水实测**,不是拍脑袋:200 个并发 3 跑了 131 秒
|
||
# = **1.53 个/秒 ≈ 5,500 个/小时**。瓶颈不在查询速度,而在调度频率。
|
||
# 400 个 × 0.65 秒 ≈ **4.4 分钟**跑完,10 分钟一轮
|
||
# = **2,400 个/小时**,7,784 个约 **3.2 小时**补完。
|
||
#
|
||
# ⚠️ 一轮时长必须**明显小于间隔**:调度器是**串行**的
|
||
# (见 scheduler.run_due_jobs 的注释:作业一个一个跑),
|
||
# 我的作业跑着的时候 CK 巡检/重登都得等着。所以宁可轮次多一些,
|
||
# 也不要一轮跑太久 —— 4.4 分钟 / 10 分钟是刻意留出的余量。
|
||
#
|
||
# 想更快就调大 `batch_size`(账号列表里那套),但**跑得越快越容易被风控**,
|
||
# 而风控是所有账号一起受影响。
|
||
# 「同一账号多久重检」= 查过的账号 7 天后再查(界面上的那个字段)。
|
||
# ⚠️ 它**不参与调度** —— 调度频率由 run_interval_seconds 决定。
|
||
interval_seconds=7 * 24 * 3600,
|
||
run_interval_seconds=5 * 60,
|
||
batch_size=400,
|
||
concurrency=3,
|
||
run=run_account_overview_refresh,
|
||
)
|
||
)
|
||
register_job(
|
||
JobSpec(
|
||
key=CK_HEALTH_KEY,
|
||
title="CK 自动巡检",
|
||
# interval_seconds = 单账号多久重新检测一次(不是作业周期;
|
||
# 作业每个 tick 都跑)。全库 12,881 条按 5 分钟一轮、单轮 200 条
|
||
# 反推,吞吐 40 条/分钟,够 6 小时内覆盖一遍(规划 §7.3)。
|
||
interval_seconds=6 * 3600,
|
||
batch_size=200,
|
||
concurrency=5,
|
||
run=run_ck_health,
|
||
)
|
||
)
|