填坑日记:Reranker 超时之谜与 Docker Compose 健康检查陷阱
今天干了什么
三件事,从午后到傍晚,一次性收尾了之前遗留的坑。
坑一:Reranker 120 秒超时
症状:上周给 RAG 平台加了 BGE-Reranker 重排序,模型也下好了,代码也改了——但一跑查询就 120 秒超时。
排查过程:
看了日志才发现,CrossEncoder 初始化时压根没管本地缓存,直接跨墙去连 huggingface.co,在国内网络下直接卡死。
# 原代码 — 没有限制从哪加载
self.model = CrossEncoder(model_name, max_length=512, device="cpu")
修复:
# 先尝试只读本地缓存
try:
self.model = CrossEncoder(
model_name,
max_length=512,
device="cpu",
local_files_only=True, # 👈 关键
)
except Exception:
# 缓存不完整才走镜像下载
os.environ.setdefault("HF_ENDPOINT", "https://hf-mirror.com")
self.model = CrossEncoder(model_name, max_length=512, device="cpu")
效果:加载从 120 秒降到 2.4 秒。
教训:模型下载和加载要分开处理——下载时走镜像,加载时读缓存。混在一起就是找罪受。
坑二:Qdrant v1.8.4 的健康检查 curl 去哪儿了
症状:Docker Compose 里配了 condition: service_healthy,依赖 Qdrant 健康检查通过后才启动 App,结果 Qdrant 一直 unhealthy,App 永远起不来。
排查:docker exec 进去一看——镜像里既没有 curl,也没有 wget。
$ docker exec qdrant which curl
(no output)
$ docker exec qdrant which wget
(no output)
Qdrant v1.8.4 用的是精简版 Debian,只装了运行时必需的东西。
尝试过的方案:
- ❌ 改用
wget——也没有 - ❌ 用
sh -c "exec 3<>/dev/tcp/..."——不是 bash,不支持 /dev/tcp - ❌
apt-get install curl——能装,但容器重建就没了
最终方案:去掉 condition: service_healthy,直接用 depends_on: [qdrant]。反正 App 启动时会重试连接 Qdrant,多等几秒不影响。
教训:官方镜像不一定是开箱即用的——depends_on: condition: service_healthy 依赖容器里有网络工具。用之前先 docker exec 进去确认。
坑三:Dockerfile 忘了拷前端文件
症状:Docker 容器里 App 跑得好好的,/health 正常,但访问首页返回 404。
排查:Dockerfile 只 COPY src/ ./src/,根本没包含项目根目录的 chat.html。
# 之前 — 只有后端
COPY src/ ./src/
# 修复后 — 加上前端
COPY src/ ./src/
COPY chat.html .
教训:Docker 构建和本地跑是两码事。本地 FileResponse 能找到 chat.html 因为它在项目根目录,容器里没有就是没有。
最终状态
| 项目 | 做了什么 | 验证 |
|---|---|---|
| RAG Platform | Reranker 本地缓存加载 | 2.4s 加载,10→3 精排正常 |
| RAG Platform | 检索链路验证 | Embed→Search→Rerank 3 步通过 |
| Smart Doc Analyzer | Dockerfile 补 chat.html | 首页 HTTP 200 |
| Smart Doc Analyzer | docker-compose 修复健康检查 | up -d 成功启动 |
| Smart Doc Analyzer | Docker 镜像构建 | docker compose build 通过 |
今天学到的
local_files_only=True是本地推理的生命线——省时间也省流量- Docker 健康检查别想当然——先
docker exec进去看工具链 - Dockerfile 要像清单一样检查——少了任何一个文件,容器里就找不到
- 填坑最爽的时刻不是修好——是把坑记下来,下次不踩