Documentation
¶
Overview ¶
Package ratelimit wraps connections with a token-bucket rate limiter.
XrayR 的 RateWriter(xray buf.Writer/MultiBuffer 适配器)在此重写为包装 sing N.ExtendedConn / N.PacketConn 的令牌桶限速。sing 无内置限速器,故自实现: 在 Read/ReadBuffer/Write/WriteBuffer(以及 UDP 的 ReadPacket/WritePacket)取得 本次传输字节数 n 后,调用 *rate.Limiter.WaitN(ctx, n) 阻塞到令牌可用。
bucket 的 burst/limit 由 limiter.GetUserBucket 给出(已是 int(limit) bytes/s), 本包只负责按 bucket 限流,不做 Mbps→bytes/s 换算。
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AutoLimiter ¶
type AutoLimiter struct {
// contains filtered or unexported fields
}
AutoLimiter 是动态限速状态机,移植自 XrayR service/controller 的 AutoSpeedLimitConfig + warnedUsers/limitedUsers 逻辑(controller.go limitUser / userInfoMonitor 动态限速段,v0.9.4)。
它是纯状态机:只维护每 key 的告警计数与限速到期时间,不直接触碰 limiter/stats。由 Integrate 阶段在 Controller 周期任务里驱动——每周期 读 billing/stats 拿到本周期用户增量 (up,down),喂给 Check 判定是否施限; 施限走 limiter.UpdateInboundLimiter(把 limitTo 写进 UserInfo.SpeedLimit), 到期释放的 key 由 Release 给出、同样走 limiter 恢复原速。
语义对齐 XrayR:
- 阈值:单周期 up 或 down 超过 limit*1e6*period/8 字节即视为超速。
- WarnTimes==0:一超速立即施限。
- WarnTimes>0:需连续超速,告警计数严格大于 WarnTimes 才施限 (即第 WarnTimes+1 次连续超速触发);任一周期未超速则计数清零。
- 已处于限速中的 key 再次超速不重复施限(沿用 !ok 守卫)。
- 施限时长:end = 施加时刻 + LimitDuration*60 秒;Release 在 now>end 时(严格大于,对齐 XrayR)释放。
func NewAutoLimiter ¶
func NewAutoLimiter(limit, warnTimes, limitSpeed, limitDuration int) *AutoLimiter
NewAutoLimiter 构造动态限速状态机。参数单位对齐 XrayR AutoSpeedLimitConfig: limit/limitSpeed 为 Mbps,limitDuration 为分钟,warnTimes 为连续超速容忍次数。 limit<=0 时状态机停用(Check 恒返回未施限)。
func (*AutoLimiter) Check ¶
Check 对单个用户做单周期超速判定。up/down 为本周期(period 秒)内的字节增量 (通常来自 billing/stats 的一次 reset 读值)。
返回 (limitTo, limited):limited 为 true 表示本次判定触发了新的限速,limitTo 为应施加的限速值,单位 bytes/s(LimitSpeed*1e6/8,对齐 XrayR 写入 UserInfo.SpeedLimit 的口径)。limited 为 false 时 limitTo 为 0——包括未超速、 仍在告警累计中、以及已处于限速中再次超速这几种不产生新动作的情形。
func (*AutoLimiter) Release ¶
func (a *AutoLimiter) Release(now int64) (releasedKeys []string)
Release 释放所有到期(now > end)的限速用户,返回被释放的 key 列表,供调用方 走 limiter 恢复原速。now 为当前 Unix 秒(由调用方传入,便于测试与统一时钟)。
type Manager ¶
type Manager struct{}
Manager 是限速包装工厂,无状态。
func (*Manager) Wrap ¶
Wrap 用 bucket 包装 conn:Read/Write(含 Buffer 零拷贝路径)前后按字节数 WaitN。 bucket 为 nil 时原样返回 conn(无限速)。
func (*Manager) WrapPacket ¶
func (m *Manager) WrapPacket(bucket *rate.Limiter, conn N.PacketConn) N.PacketConn
WrapPacket 用 bucket 包装 UDP PacketConn:ReadPacket/WritePacket 按字节数 WaitN。 bucket 为 nil 时原样返回 conn(无限速)。
type RateConn ¶
type RateConn struct {
N.ExtendedConn
// contains filtered or unexported fields
}
RateConn 包装 N.ExtendedConn,在每次读写按实际字节数向令牌桶取令牌。
type RatePacketConn ¶
type RatePacketConn struct {
N.PacketConn
// contains filtered or unexported fields
}
RatePacketConn 包装 N.PacketConn,对 UDP 收发按字节数向令牌桶取令牌。
func (*RatePacketConn) ReadPacket ¶
func (*RatePacketConn) Upstream ¶
func (c *RatePacketConn) Upstream() any
Upstream 供 sing 的解包链识别底层连接。