perf: 抢购流程第一层优化

- timer: 多NTP源取中位数提高精度,新增wait_until_early提前触发
- snatcher: 并发2个tab竞争抢购,reload用commit级别不等渲染
- snatcher: 重试间隔从300ms降到50ms,最大重试5次
- snatcher: 用waitForSelector替代固定sleep,按钮出现即点击
- snatcher: 开售前500ms发起reload,抢占先机
- main.py: 同步所有优化
This commit is contained in:
2026-04-01 14:39:03 +08:00
parent 8b64d7e69e
commit 20dfda28e3
3 changed files with 268 additions and 155 deletions

View File

@@ -3,47 +3,67 @@ import asyncio
import ntplib
from datetime import datetime
class PrecisionTimer:
def __init__(self):
self.offset = 0 # 服务器时间 - 本地时间
self.offset = 0 # 服务器时间 - 本地时间
def sync_time(self):
"""
同步 NTP 时间,计算偏移量
"""
try:
client = ntplib.NTPClient()
response = client.request('pool.ntp.org', version=3)
self.offset = response.tx_time - time.time()
print(f"时间同步完成,偏移量: {self.offset:.3f}s")
except Exception as e:
print(f"NTP同步失败: {e},将使用系统时间")
"""多次 NTP 同步取中位数,提高精度"""
offsets = []
servers = ['ntp.aliyun.com', 'ntp.tencent.com', 'pool.ntp.org']
for server in servers:
try:
client = ntplib.NTPClient()
resp = client.request(server, version=3)
offsets.append(resp.tx_time - time.time())
except Exception:
continue
if offsets:
offsets.sort()
self.offset = offsets[len(offsets) // 2]
print(f"时间同步完成,偏移量: {self.offset:.3f}s (采样{len(offsets)}个)")
else:
print("NTP同步失败将使用系统时间")
def get_server_time(self):
return time.time() + self.offset
async def wait_until(self, target_time_str):
"""
等待直到目标时间 (格式: 2026-02-01 10:00:00)
"""
"""等待直到目标时间,最后阶段忙等保证精度"""
target_dt = datetime.strptime(target_time_str, "%Y-%m-%d %H:%M:%S")
target_timestamp = target_dt.timestamp()
print(f"正在等待目标时间: {target_time_str}")
target_ts = target_dt.timestamp()
print(f"等待目标时间: {target_time_str}")
while True:
current_time = self.get_server_time()
remaining = target_timestamp - current_time
now = self.get_server_time()
remaining = target_ts - now
if remaining <= 0:
print("目标时间已到!触发抢购!")
print("目标时间已到!")
break
# 动态调整调整休眠时间以节省 CPU 并保持精度
if remaining > 1:
await asyncio.sleep(remaining - 0.5)
elif remaining > 10:
await asyncio.sleep(remaining - 10)
elif remaining > 2:
await asyncio.sleep(0.5)
elif remaining > 0.1:
await asyncio.sleep(0.01)
# remaining <= 0.1: 忙等,不 sleep
async def wait_until_early(self, target_time_str, early_ms=500):
"""提前 early_ms 毫秒触发,用于需要预操作的场景"""
target_dt = datetime.strptime(target_time_str, "%Y-%m-%d %H:%M:%S")
target_ts = target_dt.timestamp() - (early_ms / 1000.0)
while True:
now = self.get_server_time()
remaining = target_ts - now
if remaining <= 0:
break
elif remaining > 10:
await asyncio.sleep(remaining - 10)
elif remaining > 2:
await asyncio.sleep(0.5)
elif remaining > 0.1:
await asyncio.sleep(0.01)
else:
# 最后一刻进入忙等以获取最高精度
pass