优化节点分配逻辑,使用 edge id 固定轮换顺位;日志与 journal 集成;完善命令执行后的资源清理
This commit is contained in:
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user