保活服务:定期向指定URL发送GET请求
| 13 | |
| 14 | |
| 15 | class KeepAliveService: |
| 16 | """保活服务:定期向指定URL发送GET请求""" |
| 17 | |
| 18 | def __init__(self): |
| 19 | self._task: Optional[asyncio.Task] = None |
| 20 | |
| 21 | async def _run(self, url: str, interval: int): |
| 22 | """保活循环,读取到有效URL才会被调用""" |
| 23 | log.info(f"[KeepAlive] 保活任务启动,URL={url},间隔={interval}s") |
| 24 | while True: |
| 25 | try: |
| 26 | response = await get_async(url, timeout=30.0) |
| 27 | log.info(f"[KeepAlive] GET {url} -> {response.status_code}") |
| 28 | except asyncio.CancelledError: |
| 29 | raise |
| 30 | except Exception as e: |
| 31 | log.warning(f"[KeepAlive] GET {url} 失败: {e}") |
| 32 | |
| 33 | try: |
| 34 | await asyncio.sleep(interval) |
| 35 | except asyncio.CancelledError: |
| 36 | raise |
| 37 | |
| 38 | async def start(self): |
| 39 | """ |
| 40 | 启动保活服务。 |
| 41 | 仅当配置了有效的保活URL时才创建后台任务,否则零开销。 |
| 42 | """ |
| 43 | if self._task and not self._task.done(): |
| 44 | # 已有任务在运行,不重复启动 |
| 45 | return |
| 46 | |
| 47 | url = await get_keepalive_url() |
| 48 | interval = await get_keepalive_interval() |
| 49 | |
| 50 | if not url or not url.strip(): |
| 51 | log.debug("[KeepAlive] 未配置保活URL,保活服务不启动") |
| 52 | return |
| 53 | |
| 54 | if interval <= 0: |
| 55 | log.warning(f"[KeepAlive] 保活间隔无效({interval}),保活服务不启动") |
| 56 | return |
| 57 | |
| 58 | self._task = asyncio.create_task( |
| 59 | self._run(url.strip(), interval), name="keepalive_service" |
| 60 | ) |
| 61 | |
| 62 | async def stop(self): |
| 63 | """停止保活服务""" |
| 64 | if self._task and not self._task.done(): |
| 65 | self._task.cancel() |
| 66 | try: |
| 67 | await self._task |
| 68 | except asyncio.CancelledError: |
| 69 | pass |
| 70 | log.info("[KeepAlive] 保活服务已停止") |
| 71 | self._task = None |
| 72 |