优化节点分配逻辑,使用 edge id 固定轮换顺位;日志与 journal 集成;完善命令执行后的资源清理

This commit is contained in:
2025-08-19 11:09:58 +08:00
parent b6731f8442
commit 0c32337168
10 changed files with 75 additions and 31 deletions

View File

@@ -37,7 +37,7 @@ func FindCitiesWithEdgesCount(tx *gorm.DB) ([]model.City, error) {
return cities, nil
}
func AppendCityOffset(tx *gorm.DB, city int, offset int) error {
func UpdateCityOffset(tx *gorm.DB, city int, offset int) error {
if offset < 0 {
return fmt.Errorf("offset must be non-negative")
}

View File

@@ -2,9 +2,10 @@ package actions
import (
"fmt"
"zzman/model"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"zzman/model"
)
const batchSize = 1000
@@ -18,9 +19,9 @@ func FindEdgesByCity(tx *gorm.DB, cityId int) ([]model.Edge, error) {
return edges, nil
}
func SliceActiveEdgesByCity(tx *gorm.DB, cityId int, offset int, limit int) ([]model.Edge, error) {
func SliceActiveEdges(tx *gorm.DB, cityId int, afterEdgeId int, count int) ([]model.Edge, error) {
var edges []model.Edge
err := tx.Limit(limit).Offset(offset).Find(&edges, "city_id = ? and active = 1", cityId).Error
err := tx.Limit(count).Find(&edges, "id > ? and city_id = ? and active = 1", afterEdgeId, cityId).Error
if err != nil {
return nil, fmt.Errorf("failed to find edges with offset: %w", err)
}
@@ -34,10 +35,7 @@ func SaveEdges(tx *gorm.DB, edges []model.Edge) error {
// 分批处理边缘设备数据
for i := 0; i < len(edges); i += batchSize {
end := i + batchSize
if end > len(edges) {
end = len(edges)
}
end := min(i+batchSize, len(edges))
batch := edges[i:end]
err := tx.Clauses(clause.OnConflict{

View File

@@ -7,6 +7,8 @@ import (
"zzman/clients/jd"
"zzman/model"
u "zzman/util"
"gorm.io/gorm"
)
type UpdateArgs struct {
@@ -14,7 +16,6 @@ type UpdateArgs struct {
}
func Update(args ...UpdateArgs) error {
var tx = model.DB
var arg UpdateArgs
if len(args) > 0 {
arg = args[0]
@@ -22,6 +23,12 @@ func Update(args ...UpdateArgs) error {
arg.Mock = false
}
return model.DB.Transaction(func(tx *gorm.DB) error {
return update(tx, arg)
})
}
func update(tx *gorm.DB, arg UpdateArgs) error {
gateways, err := FindGateways(tx)
if err != nil {
return fmt.Errorf("获取所有网关失败:%w", err)
@@ -56,7 +63,7 @@ func Update(args ...UpdateArgs) error {
// 按城市循环,对比并更新网关配置
for iCity, city := range cities {
// 如果每个网关在此城市都有节点且无需改变,就不需要从云端拉取城市节点信息
// 如果每个网关在此城市都有节点且无需改变,就不需要重新分配节点
// 相当于直接重新提交配置,此流程下配置更新是幂等的
var gateways2Update []model.Gateway
for _, gateway := range gateways {
@@ -77,32 +84,29 @@ func Update(args ...UpdateArgs) error {
continue
}
// 否则,正常从云端拉取城市节点信息
// 否则获取足量新节点
offset := city.Offset
count := len(gateways2Update)
if count > city.EdgesCount {
slog.Warn("城市节点数量不足,跳过本次更新", "城市", city.Name, "节点数", city.EdgesCount, "网关数", count)
continue
}
if offset+count > city.EdgesCount {
slog.Debug("城市节点不足,将循环使用节点", "城市", city.Name, "节点数", city.EdgesCount, "网关数", count)
offset = 0
}
edges, err := SliceActiveEdgesByCity(tx, city.Id, offset, count)
edges, err := SliceActiveEdges(tx, city.Id, offset, count)
if err != nil {
return fmt.Errorf("查询城市 %s 可用节点失败:%w", city.Name, err)
}
if len(edges) < count {
slog.Debug("城市节点不足,将循环使用节点", "城市", city.Name, "节点数", city.EdgesCount, "网关数", count)
edges, err = SliceActiveEdgesByCity(tx, city.Id, 0, count)
edges, err = SliceActiveEdges(tx, city.Id, 0, count)
if err != nil {
return fmt.Errorf("查询城市 %s 可用节点失败:%w", city.Name, err)
}
offset = 0
}
offset = edges[len(edges)-1].Id
// 更新网关配置
var configs2Create []model.Config
var configs2Update []model.ConfigUpdate
@@ -113,7 +117,7 @@ func Update(args ...UpdateArgs) error {
newConfig := edges[iGateway]
if exists {
fmt.Printf("\t网关 %s 变更节点: %s -> %s\n", gateway.Macaddr, oldConfig.Macaddr, newConfig.Macaddr)
slog.Debug("网关配置变更", "网关", gateway.Macaddr, "旧节点", oldConfig.Macaddr, "新节点", newConfig.Macaddr)
configs2Update = append(configs2Update, model.ConfigUpdate{
Id: oldConfig.Id,
@@ -129,7 +133,7 @@ func Update(args ...UpdateArgs) error {
},
}
} else {
fmt.Printf("\t网关 %s 新增节点: %s\n", gateway.Macaddr, newConfig.Macaddr)
slog.Debug("网关配置新增", "网关", gateway.Macaddr, "新节点", newConfig.Macaddr)
configs2Create = append(configs2Create, model.Config{
Cityhash: city.Hash,
@@ -160,7 +164,7 @@ func Update(args ...UpdateArgs) error {
if err != nil {
return fmt.Errorf("更新配置失败:%w", err)
}
err = AppendCityOffset(tx, city.Id, offset+count)
err = UpdateCityOffset(tx, city.Id, offset)
if err != nil {
return fmt.Errorf("更新城市 %s 的偏移量失败:%w", city.Name, err)
}
@@ -180,11 +184,11 @@ func Update(args ...UpdateArgs) error {
setup++
}
}
fmt.Printf("提交网关 %s 配置: %d 变更, %d 新增\n", gateway.Macaddr, change, setup)
slog.Info("提交网关配置", "网关", gateway.Macaddr, "变更", change, "新增", setup)
// 提交配置到云端:配置版本 gateway.ConfigVersion
if arg.Mock {
fmt.Printf("[MOCK] 配置网关 %s:\n%v\n", gateway.Macaddr, edges)
slog.Info("[MOCK] 配置网关", "网关", gateway.Macaddr, "配置", edges)
} else {
err := jd.GatewayConfigSet(gateway.ConfigVersion, gateway.Macaddr, edges)
if err != nil {