fix(agent): 修复资产重复注册(每10s新建) + 批量删除400
agent 自动注册前按 hostname 显式查重(asset_servers.hostname 无 UNIQUE 索引,OnConflict 失效导致 Agent 每次上报都 INSERT 新记录,资产越来越多)。
批量删除 BatchDeleteServers 对齐前端 {ids} 格式(原期望裸 []uint 导致 ShouldBindJSON 解析失败 400)。
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
1 parent
f820f0271f
commit
b7780c5a5a
2 files changed
+22
-4
No files matched your search
@@ -163,12 +163,26 @@ func (h *AgentHandler) ReceiveReport(c *gin.Context) {
|
|||||||
result = h.db.Exec(updateSQL2, args2...)
|
result = h.db.Exec(updateSQL2, args2...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果还是没匹配到 —— 自动注册新服务器(UPSERT 防重复)
|
// 如果还是没匹配到 —— 按 hostname 显式查重后再注册 // Logan.Li
|
||||||
|
// asset_servers.hostname 无 UNIQUE 索引,OnConflict 不可靠,故先 First 查重,
|
||||||
|
// 避免 Agent 每次上报(10s)都新建记录导致资产越来越多。
|
||||||
if result.RowsAffected == 0 {
|
if result.RowsAffected == 0 {
|
||||||
osName := ""
|
osName := ""
|
||||||
if req.System != nil {
|
if req.System != nil {
|
||||||
osName = req.System.OSVersion
|
osName = req.System.OSVersion
|
||||||
}
|
}
|
||||||
|
var existing model.Server
|
||||||
|
if h.db.Where("hostname = ?", req.Hostname).First(&existing).Error == nil {
|
||||||
|
// 已自动注册过 → 仅更新实时指标,不重复创建
|
||||||
|
h.db.Model(&existing).Updates(map[string]interface{}{
|
||||||
|
"ip": matchIP, "os": osName, "cpu": req.CPU.CoreCount,
|
||||||
|
"memory": memMB, "disk": diskGB, "status": "running",
|
||||||
|
"agent_status": "online", "agent_version": req.AgentVersion,
|
||||||
|
"cpu_usage": req.CPU.UsagePercent, "memory_usage": req.Memory.UsagePercent,
|
||||||
|
"disk_usage": diskAvg,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 真正的新主机 → 注册(OnConflict 作为并发双保险)
|
||||||
newServer := model.Server{
|
newServer := model.Server{
|
||||||
Hostname: req.Hostname,
|
Hostname: req.Hostname,
|
||||||
IP: matchIP,
|
IP: matchIP,
|
||||||
@@ -186,7 +200,6 @@ func (h *AgentHandler) ReceiveReport(c *gin.Context) {
|
|||||||
MemoryUsage: req.Memory.UsagePercent,
|
MemoryUsage: req.Memory.UsagePercent,
|
||||||
DiskUsage: diskAvg,
|
DiskUsage: diskAvg,
|
||||||
}
|
}
|
||||||
// ON DUPLICATE KEY UPDATE — 若 hostname 已存在则更新字段(防重复注册)
|
|
||||||
if err := h.db.Clauses(clause.OnConflict{
|
if err := h.db.Clauses(clause.OnConflict{
|
||||||
Columns: []clause.Column{{Name: "hostname"}},
|
Columns: []clause.Column{{Name: "hostname"}},
|
||||||
DoUpdates: clause.AssignmentColumns([]string{
|
DoUpdates: clause.AssignmentColumns([]string{
|
||||||
@@ -202,6 +215,7 @@ func (h *AgentHandler) ReceiveReport(c *gin.Context) {
|
|||||||
req.Hostname, matchIP, req.CPU.CoreCount, memMB, diskGB, osName)
|
req.Hostname, matchIP, req.CPU.CoreCount, memMB, diskGB, osName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WebSocket 广播:向所有前端客户端推送该主机的最新指标 // Logan.Li
|
// WebSocket 广播:向所有前端客户端推送该主机的最新指标 // Logan.Li
|
||||||
if h.hubMetrics != nil && result.RowsAffected > 0 {
|
if h.hubMetrics != nil && result.RowsAffected > 0 {
|
||||||
|
|||||||
@@ -169,11 +169,15 @@ func (h *ServerHandlerV2) BatchCreateServers(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *ServerHandlerV2) BatchDeleteServers(c *gin.Context) {
|
func (h *ServerHandlerV2) BatchDeleteServers(c *gin.Context) {
|
||||||
var ids []uint
|
// 前端发 { ids: [...] },对齐格式(原期望裸 []uint 导致解析失败 400) // Logan.Li
|
||||||
if err := c.ShouldBindJSON(&ids); err != nil {
|
var req struct {
|
||||||
|
IDs []uint `json:"ids"`
|
||||||
|
}
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil || len(req.IDs) == 0 {
|
||||||
utils.BadRequest(c, "请求参数错误")
|
utils.BadRequest(c, "请求参数错误")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
ids := req.IDs
|
||||||
// 清理关联数据
|
// 清理关联数据
|
||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
var s model.Server
|
var s model.Server
|
||||||
|
|||||||
Reference in new issue
Block a user