更新:
This commit is contained in:
@@ -49,6 +49,36 @@ async def _launch_chromium(pw, args: list[str], headless: Optional[bool] = None)
|
||||
return await pw.chromium.launch(**launch_kwargs)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 启动错峰门:批量启动大量账号时,把各 worker 的启动时刻按固定间隔排开,
|
||||
# 避免同一瞬间大量凭证校验/WS 建连/首轮拉取叠峰。
|
||||
# 空闲时单个账号启动无需等待;只有短时间内大量启动才会排队。
|
||||
# KEFU_WORKER_START_INTERVAL_SECONDS:相邻两个 worker 启动的最小间隔,默认 1.5s,<=0 关闭。
|
||||
# ---------------------------------------------------------------------------
|
||||
_start_gate = {"lock": None, "next_at": 0.0}
|
||||
|
||||
|
||||
async def _startup_stagger(account_id: int) -> None:
|
||||
try:
|
||||
interval = float(os.getenv("KEFU_WORKER_START_INTERVAL_SECONDS", "") or 1.5)
|
||||
except ValueError:
|
||||
interval = 1.5
|
||||
if interval <= 0:
|
||||
return
|
||||
if _start_gate["lock"] is None:
|
||||
_start_gate["lock"] = asyncio.Lock()
|
||||
async with _start_gate["lock"]:
|
||||
now = time.monotonic()
|
||||
wait = max(0.0, _start_gate["next_at"] - now)
|
||||
_start_gate["next_at"] = max(now, _start_gate["next_at"]) + interval
|
||||
if wait > 0:
|
||||
if wait > 5:
|
||||
logger.info(
|
||||
f"Account {account_id}: start queued, waiting {wait:.1f}s to smooth batch startup"
|
||||
)
|
||||
await asyncio.sleep(wait)
|
||||
|
||||
|
||||
def format_error(exc: BaseException) -> str:
|
||||
message = str(exc).strip()
|
||||
if "Target page, context or browser has been closed" in message:
|
||||
@@ -995,6 +1025,9 @@ class DouyinWorker:
|
||||
logger.info(f"Starting worker loop for account {self.account_id}")
|
||||
|
||||
try:
|
||||
await _startup_stagger(self.account_id)
|
||||
if self.stopping:
|
||||
return
|
||||
storage_state = await self._load_storage_state()
|
||||
cookie_info = analyze_cookie(
|
||||
json.dumps(storage_state, ensure_ascii=False) if storage_state else None
|
||||
|
||||
Reference in New Issue
Block a user