实现定时通道过期清理

This commit is contained in:
2026-05-07 14:58:11 +08:00
parent 8fc1d30578
commit a0b0be2b8e
10 changed files with 112 additions and 32 deletions

View File

@@ -62,7 +62,7 @@ func (s *channelBaiyinProvider) CreateChannels(source netip.Addr, resourceId int
}
proxy := proxyResult.Proxy
// 锁内确认状态并锁定端口,避免与状态切换并发穿透
// 取用端口
var chans []netip.AddrPort
err = g.Redsync.WithLock(proxyStatusLockKey(proxy.ID), func() error {
lockedProxy, err := q.Proxy.Where(q.Proxy.ID.Eq(proxy.ID)).Take()
@@ -85,18 +85,27 @@ func (s *channelBaiyinProvider) CreateChannels(source netip.Addr, resourceId int
return nil, err
}
// 获取可用节点
_, err = g.Asynq.Enqueue(
e.NewRemoveChannel(batch),
asynq.ProcessAt(expire),
)
if err != nil {
return nil, core.NewServErr("提交关闭通道任务失败", err)
}
// 取用节点
secret := strings.Split(u.Z(proxy.Secret), ":")
if len(secret) != 2 {
return nil, core.NewServErr(fmt.Sprintf("代理 %s 密钥格式错误", proxy.IP.String()), nil)
}
gateway := g.NewGateway(proxy.IP.String(), secret[0], secret[1])
edges, err := getAvailableEdges(gateway, filter, count)
if err != nil {
return nil, err
}
// 准备通道数据
// 绑定节点到端口
channels := make([]*m.Channel, count)
chanConfigs := make([]*g.PortConfigsReq, count)
edgeConfigs := make([]string, 0, count)
@@ -117,6 +126,7 @@ func (s *channelBaiyinProvider) CreateChannels(source netip.Addr, resourceId int
FilterProv: filter.Prov,
FilterCity: filter.City,
ExpiredAt: expire,
Proxy: &proxy,
}
// 通道配置数据
@@ -146,23 +156,12 @@ func (s *channelBaiyinProvider) CreateChannels(source netip.Addr, resourceId int
}
}
// 提交异步任务关闭通道
_, err = g.Asynq.Enqueue(
e.NewRemoveChannel(batch),
asynq.ProcessAt(expire),
)
if err != nil {
return nil, core.NewServErr("提交关闭通道任务失败", err)
}
// 保存数据
err = q.Q.Transaction(func(q *q.Query) error {
// 根据套餐类型和模式更新使用记录
isShortType := resource.Type == m.ResourceTypeShort
isLongType := resource.Type == m.ResourceTypeLong
switch {
case isShortType:
// 更新使用记录
var err error
switch resource.Type {
case m.ResourceTypeShort:
_, err = q.ResourceShort.
Where(
q.ResourceShort.ID.Eq(*resource.ShortId),
@@ -175,7 +174,7 @@ func (s *channelBaiyinProvider) CreateChannels(source netip.Addr, resourceId int
q.ResourceShort.LastAt.Value(now),
)
case isLongType:
case m.ResourceTypeLong:
_, err = q.ResourceLong.
Where(
q.ResourceLong.ID.Eq(*resource.LongId),
@@ -244,7 +243,7 @@ func (s *channelBaiyinProvider) CreateChannels(source netip.Addr, resourceId int
return nil, core.NewServErr(fmt.Sprintf("配置代理 %s 端口失败", proxy.IP.String()), err)
}
} else {
slog.Debug("提交代理端口配置", "proxy", proxy.IP.String())
slog.Debug("提交代理端口配置", "proxy", proxy.IP.String(), "count", len(chanConfigs), "remote", len(edgeConfigs))
for _, item := range chanConfigs {
str, _ := json.Marshal(item)
fmt.Println(string(str))
@@ -292,12 +291,6 @@ func (s *channelBaiyinProvider) RemoveChannels(batch string) error {
// 提交配置
if env.RunMode == env.RunModeProd {
// 断开节点连接
g.Cloud.CloudDisconnect(&g.CloudDisconnectReq{
Uuid: proxy.Mac,
Edge: &edgeConfigs,
})
// 清空通道配置
secret := strings.Split(u.Z(proxy.Secret), ":")
gateway := g.NewGateway(proxy.IP.String(), secret[0], secret[1])
@@ -305,8 +298,18 @@ func (s *channelBaiyinProvider) RemoveChannels(batch string) error {
if err != nil {
return core.NewServErr(fmt.Sprintf("清空代理 %s 端口配置失败", proxy.IP.String()), err)
}
// 断开节点连接
_, err = g.Cloud.CloudDisconnect(&g.CloudDisconnectReq{
Uuid: proxy.Mac,
Edge: &edgeConfigs,
})
if err != nil {
slog.Warn("断开云平台连接失败", "error", err.Error())
return core.NewServErr("断开云平台连接失败", err)
}
} else {
slog.Debug("清除代理端口配置", "proxy", proxy.IP)
for _, item := range configs {
str, _ := json.Marshal(item)
fmt.Println(string(str))
@@ -319,7 +322,25 @@ func (s *channelBaiyinProvider) RemoveChannels(batch string) error {
return err
}
slog.Debug("清除代理端口配置", "duration", time.Since(start).String())
slog.Debug("清除代理端口配置", "proxy", proxy.IP.String(), "batch", batch, "duration", time.Since(start).String())
return nil
}
func (s *channelBaiyinProvider) ClearExpiredChannels() error {
now := time.Now().Add(time.Hour)
var batches []struct{ BatchNo string }
err := q.Channel.Select(q.Channel.BatchNo).Where(q.Channel.ExpiredAt.Lt(now)).Group(q.Channel.BatchNo).Scan(&batches)
if err != nil {
return core.NewServErr("查询过期通道失败", err)
}
for _, batch := range batches {
err := s.RemoveChannels(batch.BatchNo)
if err != nil {
slog.Error("清理过期通道失败", "batch", batch.BatchNo, "error", err)
}
}
return nil
}
@@ -335,7 +356,7 @@ func getAvailableEdges(gateway g.GatewayClient, filter *EdgeFilter, count int) (
Assigned: u.P(false),
})
if err != nil {
return nil, core.NewBizErr("获取可用节点失败", err)
return nil, core.NewBizErr("获取可用节点失败[1]", err)
}
for id, _ := range localEdgesResp {
@@ -360,7 +381,7 @@ func getAvailableEdges(gateway g.GatewayClient, filter *EdgeFilter, count int) (
IpUnchangedTime: u.P(3600),
})
if err != nil {
return nil, core.NewBizErr("获取可用节点失败", err)
return nil, core.NewBizErr("获取可用节点失败[2]", err)
}
for _, edge := range cloudEdgesResp.Edges {