重构代理和边缘节点接口,更新请求和响应结构,添加全量节点信息返回,引入全局锁以防止并发注册;代理服务下线后相关节点也标记下线

This commit is contained in:
2025-05-27 15:08:18 +08:00
parent c08d625975
commit 933c947b3e
9 changed files with 1222 additions and 649 deletions

View File

@@ -1,6 +1,10 @@
package handlers
import (
"errors"
"gorm.io/gen/field"
"gorm.io/gorm"
"log/slog"
"platform/pkg/u"
"platform/web/auth"
edge2 "platform/web/domains/edge"
@@ -11,16 +15,11 @@ import (
s "platform/web/services"
"github.com/gofiber/fiber/v2"
"gorm.io/gen/field"
"gorm.io/gorm/clause"
)
type RegisterEdgeReq struct {
Name string `json:"name" validate:"required"`
Version int `json:"version" validate:"required"`
ISP edge2.ISP `json:"isp"`
Prov string `json:"prov"`
City string `json:"city"`
Name string `json:"name" validate:"required"`
Version int `json:"version" validate:"required"`
}
type RegisterEdgeResp struct {
@@ -28,7 +27,7 @@ type RegisterEdgeResp struct {
Host string `json:"host"`
}
func OnlineEdge(c *fiber.Ctx) (err error) {
func AssignEdge(c *fiber.Ctx) (err error) {
// 验证请求参数
var req = new(RegisterEdgeReq)
@@ -37,36 +36,64 @@ func OnlineEdge(c *fiber.Ctx) (err error) {
return err
}
// 挑选合适的转发服务
var fwd *m.Proxy
fwd, err = q.Proxy.
LeftJoin(q.Edge, q.Edge.ProxyID.EqCol(q.Proxy.ID), q.Edge.Status.Eq(1)).
Select(q.Proxy.ALL, q.Edge.ALL.Count().As("count")).
Where(q.Proxy.Type.Eq(int32(proxy2.TypeSelfHosted))).
Group(q.Proxy.ID).
Order(field.NewField("", "count").Desc()).
First()
if err != nil {
return err
// 全局锁,防止并发注册
var mutex = g.Redsync.NewMutex("edge:discovery")
if err := mutex.Lock(); err != nil {
return errors.New("服务繁忙,请稍后重试")
}
defer func() {
if ok, err := mutex.Unlock(); err != nil {
slog.Error("解锁失败", slog.Bool("ok", ok), slog.Any("err", err))
}
}()
// 保存节点信息
var edge = &m.Edge{
Name: req.Name,
Version: int32(req.Version),
Host: c.Context().RemoteIP().String(),
Isp: int32(req.ISP),
Prov: req.Prov,
City: req.City,
ProxyID: &fwd.ID,
Type: int32(edge2.TypeSelfHosted),
Status: 1,
}
err = q.Edge.Clauses(clause.OnConflict{
UpdateAll: true,
Columns: []clause.Column{{Name: "name"}},
}).Create(edge)
if err != nil {
// 检查节点
var fwd *m.Proxy
var edge *m.Edge
edge, err = q.Edge.
Where(q.Edge.Name.Eq(req.Name)).
Take()
if errors.Is(err, gorm.ErrRecordNotFound) {
// 挑选合适的转发服务
fwd, err = q.Proxy.
LeftJoin(q.Edge, q.Edge.ProxyID.EqCol(q.Proxy.ID), q.Edge.Status.Eq(1)).
Select(q.Proxy.ALL, q.Edge.ALL.Count().As("count")).
Where(q.Proxy.Type.Eq(int32(proxy2.TypeSelfHosted))).
Group(q.Proxy.ID).
Order(field.NewField("", "count").Desc()).
First()
if err != nil {
return err
}
// 保存节点信息
edge = &m.Edge{
Name: req.Name,
Version: int32(req.Version),
Type: int32(edge2.TypeSelfHosted),
ProxyID: &fwd.ID,
}
err = q.Edge.Create(edge)
if err != nil {
return err
}
} else if err == nil {
// 获取已配置的转发服务
fwd, err = q.Proxy.
Where(q.Proxy.ID.Eq(*edge.ProxyID)).
Take()
if err != nil {
return err
}
// 节点已存在,更新版本号
if edge.Version < int32(req.Version) {
_, err = q.Edge.
Where(q.Edge.ID.Eq(edge.ID)).
UpdateSimple(q.Edge.Version.Value(int32(req.Version)))
if err != nil {
return err
}
}
} else {
return err
}
@@ -77,29 +104,6 @@ func OnlineEdge(c *fiber.Ctx) (err error) {
})
}
type OfflineEdgeReq struct {
Name string `json:"name" validate:"required"`
}
func OfflineEdge(c *fiber.Ctx) (err error) {
// 验证请求参数
var req = new(OfflineEdgeReq)
err = g.Validator.Validate(c, req)
if err != nil {
return err
}
// 下线转发服务
_, err = q.Edge.
Where(q.Edge.Name.Eq(req.Name)).
UpdateSimple(q.Edge.Status.Value(0))
if err != nil {
return err
}
return c.SendStatus(fiber.StatusOK)
}
type AllEdgesAvailableReq struct {
s.EdgeFilter
Count int `json:"count"`
@@ -140,7 +144,7 @@ func AllEdgesAvailable(c *fiber.Ctx) (err error) {
edges[i] = AllEdgesAvailableRespItem{
Ip: info.Host,
Port: u.Z(info.ProxyPort),
Isp: edge2.ISPToStr(edge2.ISP(info.Isp)),
Isp: edge2.ISP(info.Isp).String(),
Prov: info.Prov,
City: info.City,
Status: info.Status,