优化通道关闭流程,只靠 batch id 索引通道

This commit is contained in:
2025-12-05 18:31:30 +08:00
parent 4a2dcabf58
commit 5649a03c47
6 changed files with 37 additions and 53 deletions

View File

@@ -1,24 +1,11 @@
package events
import (
"encoding/json"
"log/slog"
"github.com/hibiken/asynq"
)
const RemoveChannel = "channel:remove"
type RemoveChannelData struct {
Batch string `json:"batch"`
IDs []int32 `json:"ids"`
}
func NewRemoveChannel(data RemoveChannelData) *asynq.Task {
bytes, err := json.Marshal(data)
if err != nil {
slog.Error("序列化删除通道任务失败", "error", err)
return nil
}
return asynq.NewTask(RemoveChannel, bytes)
func NewRemoveChannel(batch string) *asynq.Task {
return asynq.NewTask(RemoveChannel, []byte(batch))
}

View File

@@ -162,8 +162,7 @@ type CreateChannelResultType string
// region RemoveChannels
type RemoveChannelsReq struct {
Batch string `json:"batch" validate:"required"`
Ids []int32 `json:"ids" validate:"required"`
Batch string `json:"batch" validate:"required"`
}
func RemoveChannels(c *fiber.Ctx) error {
@@ -180,7 +179,7 @@ func RemoveChannels(c *fiber.Ctx) error {
}
// 删除通道
err = s.Channel.RemoveChannels(req.Batch, req.Ids)
err = s.Channel.RemoveChannels(req.Batch)
if err != nil {
return err
}

View File

@@ -18,7 +18,7 @@ var Channel ChannelService = &channelBaiyinService{}
// 通道服务
type ChannelService interface {
CreateChannels(source netip.Addr, resourceId int32, authWhitelist bool, authPassword bool, count int, edgeFilter ...EdgeFilter) ([]*m.Channel, error)
RemoveChannels(batch string, ids []int32) error
RemoveChannels(batch string) error
}
// 授权方式

View File

@@ -180,6 +180,15 @@ func (s *channelBaiyinService) CreateChannels(source netip.Addr, resourceId int3
groups[proxy] = append(groups[proxy], channels[i])
}
// 提交异步任务关闭通道
_, 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 {
@@ -240,18 +249,6 @@ func (s *channelBaiyinService) CreateChannels(source netip.Addr, resourceId int3
return nil, err
}
// 提交异步任务关闭通道
_, err = g.Asynq.Enqueue(
e.NewRemoveChannel(e.RemoveChannelData{
Batch: batch,
IDs: core.GetIDs(channels),
}),
asynq.ProcessAt(expire),
)
if err != nil {
return nil, core.NewServErr("提交关闭通道任务失败", err)
}
// 提交配置
for proxy, chanels := range groups {
secret := strings.Split(u.Z(proxy.Secret), ":")
@@ -290,20 +287,17 @@ func (s *channelBaiyinService) CreateChannels(source netip.Addr, resourceId int3
return channels, nil
}
func (s *channelBaiyinService) RemoveChannels(batch string, ids []int32) error {
func (s *channelBaiyinService) RemoveChannels(batch string) error {
start := time.Now()
// 获取连接数据
channels, err := q.Channel.
Preload(q.Channel.Proxy).
Where(q.Channel.ID.In(ids...)).
Where(q.Channel.BatchNo.Eq(batch)).
Find()
if err != nil {
return core.NewServErr("获取通道数据失败", err)
}
if len(channels) != len(ids) {
return core.NewServErr("获取通道数据不完整", err)
}
proxies := make(map[string]*m.Proxy, len(channels))
groups := make(map[string][]*m.Channel, len(channels))
@@ -320,12 +314,6 @@ func (s *channelBaiyinService) RemoveChannels(batch string, ids []int32) error {
addrs[i] = netip.AddrPortFrom(channel.Proxy.IP.Addr, channel.Port)
}
// 释放端口
err = freeChans(batch, chans)
if err != nil {
return err
}
// 清空配置
for ip, channels := range groups {
proxy := proxies[ip]
@@ -352,6 +340,12 @@ func (s *channelBaiyinService) RemoveChannels(batch string, ids []int32) error {
}
}
// 释放端口
err = freeChans(batch, chans)
if err != nil {
return err
}
slog.Debug("清除代理端口配置", "time", time.Since(start).String())
return nil
}

View File

@@ -8,7 +8,6 @@ import (
"platform/pkg/env"
"platform/pkg/u"
"platform/web/events"
e "platform/web/events"
g "platform/web/globals"
m "platform/web/models"
q "platform/web/queries"
@@ -45,17 +44,11 @@ func HandleCompleteTrade(_ context.Context, task *asynq.Task) (err error) {
}
func HandleRemoveChannel(_ context.Context, task *asynq.Task) (err error) {
data := new(e.RemoveChannelData)
err = json.Unmarshal(task.Payload(), data)
if err != nil {
return fmt.Errorf("解析任务参数失败: %w", err)
}
err = s.Channel.RemoveChannels(data.Batch, data.IDs)
batch := string(task.Payload())
err = s.Channel.RemoveChannels(batch)
if err != nil {
return fmt.Errorf("删除通道失败: %w", err)
}
return nil
}