feat(status): 全文索引降级上报到控制台 —— 让静默降级看得见

上一个提交修的是"卷没挂"这个实例,这个提交修的是"它坏了几周没人发现"这个
类别问题:全文路退内存兜底后,混合检索只表现为召回变差,不报错、无告警。

- mcp-go: bleveStore 记录 persistent;health 工具多报一个 fulltext_disk。
  仍是 map[string]bool,gateway 现有反序列化不受影响(加非 bool 字段会让
  整个 health 解析失败,连带 Milvus/Neo4j 健康灯一起黑)。
- gateway: 基建灯新增「全文索引」一项,退内存时给出后果与排查方向,
  而不只是一盏灰灯。
- admin: 基建列表此前只渲染 name/up,detail 字段一直没露出——而降级原因
  恰恰只存在于 detail 里。补上渲染(离线态用琥珀色),并给「全文索引」
  补 INFRA_META(它不是独立服务,没有端口,落在容器卷上)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Blizzard
2026-07-20 13:44:48 +08:00
parent c1420b5665
commit bfd0d74c34
4 changed files with 34 additions and 2 deletions
@@ -56,6 +56,7 @@ func (h *Handler) AdminStatus(c *gin.Context) {
wg sync.WaitGroup
milvus, neo4j bool // mcp-go health
ftDisk bool // 全文索引是否落盘持久(false=退内存兜底,重启清零)
goUp bool // mcp-go 在线
goTools []toolInfo // mcp-go 注册工具
goLatency int // mcp-go 探针耗时
@@ -81,6 +82,7 @@ func (h *Handler) AdminStatus(c *gin.Context) {
var sub map[string]bool
if json.Unmarshal([]byte(res.Content), &sub) == nil {
milvus, neo4j = sub["milvus"], sub["neo4j"]
ftDisk = sub["fulltext_disk"]
}
}
}()
@@ -138,6 +140,9 @@ func (h *Handler) AdminStatus(c *gin.Context) {
{Name: "milvus", Up: milvus},
{Name: "neo4j", Up: neo4j},
{Name: "minio", Up: minioUp}, // 对象存储(报告/KB 正文/blob126
// 全文索引:mcp-go 本地 bleve,是唯一不在 128 集中存储上的检索路,
// 也是唯一会"静默降级"的一路(退内存后重启清零,检索只是变差不报错)。
{Name: "全文索引", Up: goUp && ftDisk, Detail: fulltextDetail(goUp, ftDisk)},
},
Services: []statusItem{
{Name: "gateway", Up: true, Detail: "在线"},
@@ -207,3 +212,16 @@ func humanDuration(s int) string {
}
return fmt.Sprintf("%dh%dm", m/60, m%60)
}
// fulltextDetail 说明全文(bleve)索引的持久化状态。退内存兜底时必须讲清后果——
// 否则一盏灰灯没人知道意味着"重启就没了"。
func fulltextDetail(goUp, disk bool) string {
switch {
case !goUp:
return "mcp-go 离线,无法判定"
case disk:
return "落盘持久"
default:
return "内存兜底 · 重启即清零(检查 BLEVE_PATH 与挂载卷权限)"
}
}