From 299ce821d525dbee4df12b7ffea7669bf97ba646 Mon Sep 17 00:00:00 2001 From: luorijun Date: Mon, 1 Dec 2025 12:42:51 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BE=9B=E4=B8=80=E4=B8=AA=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E6=B3=A8=E5=86=8C=E4=BB=A3=E7=90=86=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + web/handlers/proxy.go | 33 +++++++++++++++++++++++++++------ web/routes.go | 1 + web/services/channel.go | 27 ++++++++++++++++++--------- web/services/proxy.go | 39 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 86 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index a9f1b11..859c888 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ 重新实现接口 proxy 注册与注销接口: - 注册时向 redis ports 可用池中加入端口 - 注销时需要同时移除可用池与租约池中的端口(需要考虑具体实现,考虑正在使用的节点归还问题) +- 调整通道分配策略,提供一个 all set 和一个 free set,提取时取交集再取出,归还时取交集再归还。 otel 检查接口性能 diff --git a/web/handlers/proxy.go b/web/handlers/proxy.go index dd4d3bf..fda1969 100644 --- a/web/handlers/proxy.go +++ b/web/handlers/proxy.go @@ -1,11 +1,38 @@ package handlers import ( + "log/slog" + "net/netip" + "platform/pkg/env" + g "platform/web/globals" + s "platform/web/services" "time" "github.com/gofiber/fiber/v2" ) +func DebugRegisterProxyBaiYin(c *fiber.Ctx) error { + if env.RunMode != env.RunModeDev { + return fiber.ErrNotFound + } + + ok, err := g.Redis.SetNX(c.Context(), "debug:channel:register:127.0.0.1", true, 0).Result() + if err != nil { + return err + } + slog.Info("注册代理", "ok", ok) + if !ok { + return fiber.ErrConflict + } + + err = s.Proxy.RegisterBaiyin("1a:2b:3c:4d:5e:6f", netip.AddrFrom4([4]byte{127, 0, 0, 1}), "test", "test") + if err != nil { + return err + } + + return nil +} + // region 报告上线 type ProxyReportOnlineReq struct { @@ -123,8 +150,6 @@ func ProxyReportOnline(c *fiber.Ctx) (err error) { // }) } -// endregion - // region 报告下线 type ProxyReportOfflineReq struct { @@ -168,8 +193,6 @@ func ProxyReportOffline(c *fiber.Ctx) (err error) { // return nil } -// endregion - // region 报告更新 type ProxyReportUpdateReq struct { @@ -335,8 +358,6 @@ func ProxyReportUpdate(c *fiber.Ctx) (err error) { // return nil } -// endregion - type ProxyPermit struct { Id int32 `json:"id"` Expire time.Time `json:"expire"` diff --git a/web/routes.go b/web/routes.go index bf73560..d4d7669 100644 --- a/web/routes.go +++ b/web/routes.go @@ -76,4 +76,5 @@ func ApplyRouters(app *fiber.App) { // 临时 debug := app.Group("/debug") debug.Get("/sms/:phone", handlers.DebugGetSmsCode) + debug.Get("/proxy/register", handlers.DebugRegisterProxyBaiYin) } diff --git a/web/services/channel.go b/web/services/channel.go index 345c019..83af030 100644 --- a/web/services/channel.go +++ b/web/services/channel.go @@ -162,23 +162,18 @@ type ResourceView struct { } func lockChans(batch string, count int, expire time.Time) ([]netip.AddrPort, error) { - results, err := g.Redis.Eval( + chans, err := g.Redis.Eval( context.Background(), RedisScriptLockChans, []string{"channel"}, batch, count, expire.Unix(), - ).Result() + ).StringSlice() if err != nil { return nil, core.NewBizErr("获取通道失败", err) } - chans, ok := results.([]string) - if !ok { - return nil, core.NewServErr("转换通道数据失败") - } - addrs := make([]netip.AddrPort, len(chans)) for i, ch := range chans { addr, err := netip.ParseAddrPort(ch) @@ -200,11 +195,11 @@ local expire = tonumber(ARGV[3]) local chans_key = key .. ":chans" local lease_key = key .. ":lease:" .. batch -if redis.call("SCARD", key) < count then +if redis.call("SCARD", chans_key) < count then return nil end -local ports = redis.call("SPOP", key, count) +local ports = redis.call("SPOP", chans_key, count) redis.call("SET", lease_key, cjson.encode({ p = ports, @@ -244,6 +239,20 @@ redis.call("DEL", lease_key) return chans ` +func registerChans(chans []netip.AddrPort) error { + strs := make([]string, len(chans)) + for i, ch := range chans { + strs[i] = ch.String() + } + + err := g.Redis.SAdd(context.Background(), "channel:chans", strs).Err() + if err != nil { + return core.NewBizErr("注册通道失败", err) + } + + return nil +} + // 错误信息 var ( ErrResourceNotExist = core.NewBizErr("套餐不存在") diff --git a/web/services/proxy.go b/web/services/proxy.go index de57ee5..d51b247 100644 --- a/web/services/proxy.go +++ b/web/services/proxy.go @@ -1,6 +1,11 @@ package services import ( + "fmt" + "net/netip" + "platform/pkg/u" + "platform/web/core" + "platform/web/globals/orm" m "platform/web/models" q "platform/web/queries" "time" @@ -10,6 +15,7 @@ var Proxy = &proxyService{} type proxyService struct{} +// AllProxies 获取所有代理 func (s *proxyService) AllProxies(proxyType m.ProxyType, channels bool) ([]*m.Proxy, error) { proxies, err := q.Proxy.Where( q.Proxy.Type.Eq(int(proxyType)), @@ -23,3 +29,36 @@ func (s *proxyService) AllProxies(proxyType m.ProxyType, channels bool) ([]*m.Pr return proxies, nil } + +// RegisterBaiyin 注册新代理服务 +func (s *proxyService) RegisterBaiyin(Mac string, IP netip.Addr, username, password string) error { + + // 添加可用通道到 redis + chans := make([]netip.AddrPort, 10000) + for i := range 10000 { + chans[i] = netip.AddrPortFrom(IP, uint16(i+10000)) + } + err := registerChans(chans) + if err != nil { + return core.NewServErr("添加通道失败") + } + + // 保存代理信息 + if err := q.Proxy.Create(&m.Proxy{ + Version: 0, + Mac: Mac, + IP: orm.Inet{Addr: IP}, + Secret: u.P(fmt.Sprintf("%s:%s", username, password)), + Type: m.ProxyTypeBaiYin, + Status: m.ProxyStatusOnline, + }); err != nil { + return core.NewServErr("保存通道数据失败") + } + + return nil +} + +// UnregisterBaiyin 注销代理服务 +func (s *proxyService) UnregisterBaiyin(id int) error { + return nil +}