From 3478db383e14766ce4bd2a44f5deabbd18d4b93e Mon Sep 17 00:00:00 2001 From: jingrow Date: Thu, 1 Jan 2026 20:31:54 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=99=90=E5=88=B6=E8=A7=A3=E9=99=A4?= =?UTF-8?q?=E5=90=8E=E5=A2=9E=E5=8A=A015=E5=88=86=E9=92=9F=E7=BC=93?= =?UTF-8?q?=E5=86=B2=E6=9C=9F=E5=86=8D=E9=87=8D=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题: - 限制解除后立即重试,可能再次触发速率限制 - 没有缓冲时间,容易导致连续失败 修复: - 限制解除后,增加15分钟缓冲期 - 缓冲期内不申请证书,避免立即重试 - 优化检查间隔计算,在缓冲期结束后才重试 实现: - should_request_cert: 检查缓冲期,缓冲期内返回 False - run: 计算重试时间时加上15分钟缓冲期 - 实际重试时间 = 限制解除时间 + 15分钟 优势: - 避免立即重试再次触发限制 - 给 Let's Encrypt 足够的恢复时间 - 提高证书申请成功率 --- ssl_manager/route_watcher.py | 37 ++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/ssl_manager/route_watcher.py b/ssl_manager/route_watcher.py index b299873..332098e 100755 --- a/ssl_manager/route_watcher.py +++ b/ssl_manager/route_watcher.py @@ -179,9 +179,16 @@ class RouteWatcher: logger.debug(f"域名 {domain} 仍在速率限制期间,剩余约 {remaining_minutes} 分钟后重试") return False else: - # 限制已解除,移除记录 - del self.rate_limited_domains[domain] - logger.info(f"域名 {domain} 速率限制已解除,将重新尝试申请证书") + # 限制已解除,但再等待15分钟缓冲时间,避免立即重试再次触发限制 + buffer_seconds = 15 * 60 # 15分钟缓冲 + if current_time < retry_after + buffer_seconds: + remaining_minutes = int((retry_after + buffer_seconds - current_time) / 60) + 1 + logger.debug(f"域名 {domain} 限制已解除,等待缓冲期,剩余约 {remaining_minutes} 分钟后重试") + return False + else: + # 缓冲期已过,移除记录,允许重试 + del self.rate_limited_domains[domain] + logger.info(f"域名 {domain} 速率限制和缓冲期已过,将重新尝试申请证书") return True @@ -271,7 +278,29 @@ class RouteWatcher: while True: try: self.process_new_domains() - time.sleep(interval) + + # 计算下次检查时间:如果有速率限制的域名即将解除,提前检查 + next_check_interval = interval + current_time = time.time() + buffer_seconds = 15 * 60 # 15分钟缓冲时间 + + # 检查是否有即将解除限制的域名(包括缓冲期) + for domain, retry_after in list(self.rate_limited_domains.items()): + # 计算到可以重试的时间(限制解除时间 + 15分钟缓冲) + actual_retry_time = retry_after + buffer_seconds + + if actual_retry_time <= current_time: + # 限制和缓冲期都已过,下次检查时处理 + continue + else: + # 计算到可以重试的时间 + time_until_retry = actual_retry_time - current_time + if time_until_retry < next_check_interval: + # 在可以重试时检查,而不是等到正常检查周期 + next_check_interval = max(1, min(time_until_retry + 1, interval)) # +1 秒缓冲,至少1秒 + + time.sleep(next_check_interval) + except KeyboardInterrupt: logger.info("收到停止信号,退出服务") break