完善节点筛选机制

This commit is contained in:
2026-06-12 16:43:09 +08:00
parent 513fe78815
commit 25cacf0bca
7 changed files with 40 additions and 82 deletions

View File

@@ -1,6 +1,6 @@
## TODO ## TODO
- 日志记录 - edge.area_id 可为空,代表节点无固定地区
- 后台展示 mac, ip:port实际地区 - 后台展示 mac, ip:port实际地区
上传文件平铺到 uploads不分子文件夹 上传文件平铺到 uploads不分子文件夹

View File

@@ -669,7 +669,7 @@ create table edge (
ip inet not null, ip inet not null,
port int, port int,
isp int not null, isp int not null,
area_id int not null, area_id int,
status int not null default 0, status int not null default 0,
rtt int default 0, rtt int default 0,
loss int default 0, loss int default 0,

View File

@@ -230,23 +230,6 @@ type CreateChannelReqV3 struct {
Isp *int `json:"isp"` Isp *int `json:"isp"`
} }
func buildCreateChannelResp(result []*m.Channel, protocol int, authType s.ChannelAuthType) []*CreateChannelRespItem {
resp := make([]*CreateChannelRespItem, len(result))
for i, channel := range result {
resp[i] = &CreateChannelRespItem{
Proto: protocol,
Host: channel.Host,
IP: channel.Proxy.IP.String(),
Port: channel.Port,
}
if authType == s.ChannelAuthTypePass {
resp[i].Username = channel.Username
resp[i].Password = channel.Password
}
}
return resp
}
type CreateChannelRespItem struct { type CreateChannelRespItem struct {
Proto int `json:"-"` Proto int `json:"-"`
Host string `json:"host"` Host string `json:"host"`
@@ -474,3 +457,20 @@ type SyncChannelClearExpiredByAdminReq struct {
type SyncChannelClearExpiredByAdminResp struct { type SyncChannelClearExpiredByAdminResp struct {
Count int `json:"count"` Count int `json:"count"`
} }
func buildCreateChannelResp(result []*m.Channel, protocol int, authType s.ChannelAuthType) []*CreateChannelRespItem {
resp := make([]*CreateChannelRespItem, len(result))
for i, channel := range result {
resp[i] = &CreateChannelRespItem{
Proto: protocol,
Host: channel.Host,
IP: channel.Proxy.IP.String(),
Port: channel.Port,
}
if authType == s.ChannelAuthTypePass {
resp[i].Username = channel.Username
resp[i].Password = channel.Password
}
}
return resp
}

View File

@@ -14,7 +14,7 @@ type Edge struct {
IP orm.Inet `json:"ip" gorm:"column:ip;not null"` // 节点地址或 GOST chain addr 的 IP IP orm.Inet `json:"ip" gorm:"column:ip;not null"` // 节点地址或 GOST chain addr 的 IP
Port *uint16 `json:"port,omitempty" gorm:"column:port"` // GOST chain addr 的端口 Port *uint16 `json:"port,omitempty" gorm:"column:port"` // GOST chain addr 的端口
ISP EdgeISP `json:"isp" gorm:"column:isp"` // 运营商0-未知1-电信2-联通3-移动 ISP EdgeISP `json:"isp" gorm:"column:isp"` // 运营商0-未知1-电信2-联通3-移动
AreaID int32 `json:"area_id" gorm:"column:area_id"` // 城市地区ID AreaID *int32 `json:"area_id,omitempty" gorm:"column:area_id"` // 城市地区ID
Status EdgeStatus `json:"status" gorm:"column:status"` // 节点状态0-离线1-正常 Status EdgeStatus `json:"status" gorm:"column:status"` // 节点状态0-离线1-正常
RTT int32 `json:"rtt" gorm:"column:rtt"` // 最近平均延迟 RTT int32 `json:"rtt" gorm:"column:rtt"` // 最近平均延迟
Loss int32 `json:"loss" gorm:"column:loss"` // 最近丢包率 Loss int32 `json:"loss" gorm:"column:loss"` // 最近丢包率
@@ -41,6 +41,7 @@ const (
type EdgeISP int type EdgeISP int
const ( const (
EdgeISPUnknown EdgeISP = 0 // 未知/任意
EdgeISPTelecom EdgeISP = 1 // 电信 EdgeISPTelecom EdgeISP = 1 // 电信
EdgeISPUnicom EdgeISP = 2 // 联通 EdgeISPUnicom EdgeISP = 2 // 联通
EdgeISPMobile EdgeISP = 3 // 移动 EdgeISPMobile EdgeISP = 3 // 移动

View File

@@ -1,13 +1,11 @@
package web package web
import ( import (
"fmt"
"platform/pkg/env" "platform/pkg/env"
auth2 "platform/web/auth" auth2 "platform/web/auth"
"platform/web/core" "platform/web/core"
"platform/web/globals" "platform/web/globals"
"platform/web/handlers" "platform/web/handlers"
"strings"
"time" "time"
q "platform/web/queries" q "platform/web/queries"
@@ -51,46 +49,6 @@ func ApplyRouters(app *fiber.App) {
} }
return ctx.JSON(resp) return ctx.JSON(resp)
}) })
debug.Get("/gen-edge", func(ctx *fiber.Ctx) error {
areas, err := q.Area.Where(q.Area.Level.Eq(2)).Find()
if err != nil {
return err
}
sb := strings.Builder{}
sb.WriteString("INSERT INTO edge (type, version, mac, ip, port, isp, area_id, status) VALUES\n")
for i, area := range areas {
// jh edges
for j := range 20 {
fmt.Fprintf(&sb, "(2, 1, 'jh-%d-%d-%d', '192.168.50.%d', %d, 0, %d, 1)", area.ID, j+1, i+44001, j+2, i+44001, area.ID)
sb.WriteString(",\n")
}
// jg edges
for j := range 10 {
var ip string
var n int
if i < 100 {
ip = "192.168.0.232"
n = 1
} else if i < 200 {
ip = "192.168.59.236"
n = 2
} else {
ip = "192.168.59.237"
n = 3
}
fmt.Fprintf(&sb, "(2, 1, 'jg-%d-%d-%d', '%s', %d, 0, %d, 1)", area.ID, n, i*10+j+20001, ip, i*10+j+20001, area.ID)
if i < len(areas)-1 || j < 9 {
sb.WriteString(",\n")
}
}
}
sb.WriteString(";\n")
return ctx.SendString(sb.String())
})
} }
} }

View File

@@ -40,6 +40,10 @@ type channelServer struct {
} }
func (s *channelServer) CreateChannels(source netip.Addr, resourceNo string, authWhitelist bool, authPassword bool, count int, edgeFilter *EdgeFilter) ([]*m.Channel, error) { func (s *channelServer) CreateChannels(source netip.Addr, resourceNo string, authWhitelist bool, authPassword bool, count int, edgeFilter *EdgeFilter) ([]*m.Channel, error) {
if edgeFilter == nil {
edgeFilter = &EdgeFilter{}
}
var area *m.Area var area *m.Area
if edgeFilter.AreaID != nil { if edgeFilter.AreaID != nil {
var err error var err error
@@ -265,8 +269,8 @@ func persistChannelCreate(ctx *channelCreateContext, channels []*m.Channel) erro
BatchNo: ctx.BatchNo, BatchNo: ctx.BatchNo,
Count: int32(ctx.Count), Count: int32(ctx.Count),
ISP: u.X(ctx.Filter.Isp.String()), ISP: u.X(ctx.Filter.Isp.String()),
Prov: prov, Prov: u.Ternary(ctx.Filter.AreaID != nil, prov, nil),
City: city, City: u.Ternary(ctx.Filter.AreaID != nil, city, nil),
IP: orm.Inet{Addr: ctx.Source}, IP: orm.Inet{Addr: ctx.Source},
Time: ctx.Now, Time: ctx.Now,
}); err != nil { }); err != nil {

View File

@@ -10,7 +10,7 @@ import (
q "platform/web/queries" q "platform/web/queries"
"strings" "strings"
"gorm.io/gen" "gorm.io/gen/field"
) )
type channelGostProvider struct{} type channelGostProvider struct{}
@@ -37,7 +37,7 @@ func (s *channelGostProvider) prepareCreate(ctx *channelCreateContext) (*channel
serviceName := gostServiceName(ctx.BatchNo, port) serviceName := gostServiceName(ctx.BatchNo, port)
channel := newBaseChannel(ctx, port) channel := newBaseChannel(ctx, port)
channel.EdgeID = u.P(edge.ID) channel.EdgeID = u.P(edge.ID)
channel.EdgeRef = u.P(serviceName) channel.EdgeRef = u.P(edge.Mac)
channel.IP = u.P(edge.IP) channel.IP = u.P(edge.IP)
service := &g.GostServiceConfig{ service := &g.GostServiceConfig{
@@ -141,40 +141,34 @@ func (s *channelGostProvider) selectEdge(filter *EdgeFilter, area *m.Area, count
filter = &EdgeFilter{} filter = &EdgeFilter{}
} }
conds := []gen.Condition{ do := q.Edge.Where(
q.Edge.Type.Eq(int(m.EdgeTypeGostChain)), q.Edge.Type.Eq(int(m.EdgeTypeGostChain)),
q.Edge.Status.Eq(int(m.EdgeStatusNormal)), q.Edge.Status.Eq(int(m.EdgeStatusNormal)),
)
if filter.Isp != nil {
do = do.Where(q.Edge.ISP.In(int(m.EdgeISPUnknown), int(*filter.Isp)))
} }
if isp := u.X(filter.Isp.String()); isp != nil {
conds = append(conds, q.Edge.ISP.Eq(int(*filter.Isp)))
}
query := q.Edge.Where(conds...)
if area != nil { if area != nil {
switch area.Level { switch area.Level {
case m.AreaLevelProvince: case m.AreaLevelProvince:
edgeArea := q.Area.As("EdgeArea") edgeArea := q.Area.As("EdgeArea")
query = query. do = do.
Join(edgeArea, edgeArea.ID.EqCol(q.Edge.AreaID)). Where(edgeArea.ParentID.Eq(area.ID)).
Where(edgeArea.ParentID.Eq(area.ID)) Join(edgeArea, edgeArea.ID.EqCol(q.Edge.AreaID))
case m.AreaLevelCity: case m.AreaLevelCity:
query = query.Where(q.Edge.AreaID.Eq(area.ID)) do = do.Where(q.Edge.AreaID.Eq(area.ID))
default: default:
return nil, core.NewBizErr("地区层级不支持") return nil, core.NewBizErr("地区层级不支持")
} }
} }
edges, err := query. edges, err := do.
Order(q.Edge.ID). Order(field.NewUnsafeFieldRaw("random()")).
Limit(count). Limit(count).
Find() Find()
if err != nil { if err != nil {
return nil, core.NewBizErr("查询可用节点失败", err) return nil, core.NewBizErr("查询可用节点失败", err)
} }
return expandGostEdges(edges, count)
}
func expandGostEdges(edges []*m.Edge, count int) ([]*m.Edge, error) {
if len(edges) == 0 { if len(edges) == 0 {
return nil, core.NewBizErr("地区可用节点数量不足") return nil, core.NewBizErr("地区可用节点数量不足")
} }
@@ -183,6 +177,7 @@ func expandGostEdges(edges []*m.Edge, count int) ([]*m.Edge, error) {
for i := range count { for i := range count {
result[i] = edges[i%len(edges)] result[i] = edges[i%len(edges)]
} }
return result, nil return result, nil
} }