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:
@@ -17,6 +17,8 @@ const INFRA_META: Record<string, { role: string; port: string; icon: IconName }>
|
||||
milvus: { role: "向量检索库", port: "19530", icon: "db" },
|
||||
neo4j: { role: "图关系库", port: "7687", icon: "bus" },
|
||||
minio: { role: "对象存储 (OSS)", port: "9000", icon: "db" },
|
||||
// 全文索引不是独立服务,是 mcp-go 进程内的本地 bleve —— 没有端口,落在容器卷上。
|
||||
全文索引: { role: "全文检索 (bleve)", port: "本地卷", icon: "db" },
|
||||
};
|
||||
|
||||
function toolCategory(t: string): string {
|
||||
@@ -313,9 +315,15 @@ export function StatusPage() {
|
||||
const meta = INFRA_META[item.name];
|
||||
return (
|
||||
<div key={item.name} className="flex items-center justify-between text-xs pb-3 border-b border-slate-100 last:border-0 last:pb-0">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex min-w-0 items-center gap-2">
|
||||
<span className="font-bold text-slate-800">{item.name}</span>
|
||||
<span className="text-[10px] text-slate-400">{meta?.role || "后端组件"}</span>
|
||||
{/* detail 是降级原因/后果的唯一载体(如"内存兜底·重启即清零"),必须露出来 */}
|
||||
{item.detail && (
|
||||
<span className={`truncate text-[10px] ${item.up ? "text-slate-400" : "text-amber-600"}`} title={item.detail}>
|
||||
· {item.detail}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<code className="text-[10px] text-slate-400 font-mono bg-slate-100 px-1.5 py-0.5 rounded">
|
||||
|
||||
@@ -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 正文/blob,126)
|
||||
// 全文索引: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 与挂载卷权限)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ import (
|
||||
// 落盘不可用时退回内存索引(功能在、重启会丢),好过全文路全哑。
|
||||
type bleveStore struct {
|
||||
idx bleve.Index
|
||||
// persistent=false 表示退了内存兜底:功能在但重启即清零。这是**静默降级**——
|
||||
// 混合检索只会少一路召回、不报错,所以必须上报出去(health → 控制台),否则没人发现。
|
||||
persistent bool
|
||||
}
|
||||
|
||||
// bleveMapping:text 字段用 cjk 分词器(bigram,能切中文,否则默认标准分词器把整段中文当一个
|
||||
@@ -62,7 +65,7 @@ func openBleve() *bleveStore {
|
||||
return memBleve()
|
||||
}
|
||||
log.Printf("[rag] bleve 全文索引落盘就绪: %s", path)
|
||||
return &bleveStore{idx: idx}
|
||||
return &bleveStore{idx: idx, persistent: true}
|
||||
}
|
||||
|
||||
// memBleve 内存兜底:落盘不可用时退回内存索引(功能在、重启会丢),好过全文路全哑。
|
||||
|
||||
@@ -155,6 +155,9 @@ func (e *Engine) Status() map[string]bool {
|
||||
"milvus": e.mv != nil,
|
||||
"neo4j": e.graph.ready(),
|
||||
"embedding": e.embed().ready(),
|
||||
// 全文路是否落盘持久。false = 退了内存兜底,重启清零 —— 不上报的话这种降级
|
||||
// 只表现为"召回变差",看不出故障(曾因此静默坏了很久)。
|
||||
"fulltext_disk": e.bleve != nil && e.bleve.persistent,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user