- 抢购调度重构:参考 dygou_go 将 sniper 拆分为独立子模块(runner/run_control/retry/exchange/classify/config/summary/category/helpers);移除全局自适应降速与轮次上限,采用账号独立循环、统一账号级退避、单请求并发闸门与首发错峰 - 预热与建连优化:默认关闭预热(避免单账号超时连坐整机开抢),开启时转为后台非阻塞协程;WebSocket 握手超时从 10s 降至 1500ms - 双时间日志:logger 增加 SetServerOffset,校准后日志前缀自动渲染「本地时间(H虎牙估算时间)」,实现跨机器绝对毫秒对齐 - 默认配置调优:版本提升至 v0.5.0,默认线程调为 2(缓解多实例并发限流),前端自动平滑迁移 - 验证方式:go test ./... -count=1 全通,npm run build 构建正常,单测覆盖双时间与预热配置
58 lines
1.1 KiB
Go
58 lines
1.1 KiB
Go
package sniper
|
|
|
|
import (
|
|
"context"
|
|
"math/rand"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
func int32String(value int32) string {
|
|
return strconv.FormatInt(int64(value), 10)
|
|
}
|
|
|
|
func int64String(value int64) string {
|
|
return strconv.FormatInt(value, 10)
|
|
}
|
|
|
|
func sleepContext(ctx context.Context, d time.Duration) error {
|
|
timer := time.NewTimer(d)
|
|
defer timer.Stop()
|
|
select {
|
|
case <-timer.C:
|
|
return nil
|
|
case <-ctx.Done():
|
|
return ctx.Err()
|
|
}
|
|
}
|
|
|
|
func maxDuration(a, b time.Duration) time.Duration {
|
|
if a > b {
|
|
return a
|
|
}
|
|
return b
|
|
}
|
|
|
|
func maxInt(a, b int) int {
|
|
if a > b {
|
|
return a
|
|
}
|
|
return b
|
|
}
|
|
|
|
// jitterDuration 在基准退避上叠加 0-25% 的随机抖动。
|
|
//
|
|
// 多个账号同时失败时,固定退避会让它们在同一个时刻整批重试,形成周期性尖峰,
|
|
// 更容易撞上限频(参考 dygou_go 的 jitterFraction)。这里只往长了抖,不缩短,
|
|
// 保证配置值始终是退避下限。
|
|
func jitterDuration(base time.Duration) time.Duration {
|
|
if base <= 0 {
|
|
return base
|
|
}
|
|
span := int64(base) / 4
|
|
if span <= 0 {
|
|
return base
|
|
}
|
|
return base + time.Duration(rand.Int63n(span+1))
|
|
}
|