从零构建旅游知识库 RAG 系统(下):生产级部署、全链路联调与架构演进实战 相关项目代码已上传githubgiteecsdn等等关键词Docker Compose、Milvus、MongoDB、MinIO、Redis、Celery、Nginx、生产部署、全链路压测一、承上启下从“代码写完”到“系统跑起来”在本系列前两篇教程中我们已经完成了旅游 RAG 系统的核心功能开发搭建起完整的前后端业务骨架上篇前端篇实现 FastAPI 原生 JS 前端交互体系搞定大文件拖拽上传、SSE 流式对话、任务进度轮询、会话持久化等核心交互能力。中篇后端架构篇基于 LangGraph 搭建双核心流水线落地 MinerU 高精度文档解析、多模态图片摘要、BGE-M3 混合检索、RRF 结果融合、重排序优化、大模型流式生成等核心AI能力。对于开发学习者而言代码能跑只是基础能稳定、持久、无人值守运行才是生产级系统的核心标准。目前我们完成的开发环境代码存在状态易丢失、任务易中断、端口混乱、环境依赖繁杂等诸多问题距离商用、稳定落地还有最后一段核心距离。本篇作为系列终章将聚焦开发环境 → 生产环境的全流程改造逐一解决项目现存痛点通过 Docker Compose 一键编排所有基础设施抹平环境差异统一环境变量配置彻底根除代码硬编码问题Redis 替换内存存储解决服务重启状态丢失、多进程数据不共享问题Celery 替换原生后台任务实现长耗时文档导入任务不中断、可追溯Nginx 统一端口入口解决多服务跨域、端口暴露混乱问题完成全链路联调、性能压测汇总生产落地高频踩坑方案。读完本文你将拥有一套可直接部署、7×24小时稳定运行、高可用、易拓展的生产级旅游知识库 RAG 系统。二、基础设施层Docker Compose 一键拉起所有依赖服务本项目依赖向量数据库、文档数据库、对象存储、缓存中间件等多个基础服务手动安装配置繁琐、环境差异大、迁移成本高。我们采用Docker Compose统一编排所有基础设施一条命令即可完成所有服务的安装、启动、自启配置完美适配本地开发、服务器部署等各类场景。本次编排包含6大核心服务全覆盖项目所有依赖Redis缓存任务状态、接口高频数据替代原生内存存储MongoDB持久化用户对话历史、会话信息业务 MinIO存储旅游文档配图、解析后的线上图片资源EtcdMilvus 向量数据库核心依赖存储元数据信息Milvus 专属 MinIO单独存储向量索引文件和业务资源隔离Milvus核心向量数据库存储文档切片向量支撑混合检索能力。2.1 完整 docker-compose.yml 生产级配置在项目根目录新建docker-compose.yml文件复制以下全量配置所有服务默认配置自启动、数据持久化无需二次修改version: 3.8 services: # 1. Redis任务状态缓存中心 redis: image: redis:7.2-alpine container_name: kb-redis ports: - 6379:6379 restart: always command: redis-server --appendonly yes volumes: - ./data/redis:/data # 2. MongoDB对话历史持久化 mongodb: image: mongo:7.0 container_name: kb-mongo ports: - 27017:27017 restart: always environment: MONGO_INITDB_ROOT_USERNAME: ** MONGO_INITDB_ROOT_PASSWORD: ** MONGO_INITDB_DATABASE: knowledge_base volumes: - ./data/mongo:/data/db # 3. 业务MinIO旅游图片资源存储 minio: image: minio/minio:latest container_name: kb-minio ports: - 9000:9000 # API交互端口 - 9001:9001 # 可视化控制台端口 restart: always environment: MINIO_ROOT_USER: ** MINIO_ROOT_PASSWORD: ** volumes: - ./data/minio:/data command: server /data --console-address :9001 # 4. Milvus依赖Etcd元数据服务 etcd: container_name: kb-etcd image: quay.io/coreos/etcd:v3.5.5 environment: - ETCD_AUTO_COMPACTION_MODErevision - ETCD_AUTO_COMPACTION_RETENTION1000 - ETCD_QUOTA_BACKEND_BYTES4294967296 volumes: - ./data/etcd:/etcd command: etcd -advertise-client-urlshttp://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd # 5. Milvus专属MinIO向量索引存储 minio-milvus: container_name: kb-minio-milvus image: minio/minio:latest environment: MINIO_ROOT_USER: ** MINIO_ROOT_PASSWORD: ** volumes: - ./data/milvus-minio:/data command: minio server /data --console-address :9002 ports: - 9002:9002 # 6. Milvus核心向量数据库 standalone: container_name: kb-milvus image: milvusdb/milvus:v2.4.0 command: [milvus, run, standalone] environment: ETCD_ENDPOINTS: etcd:2379 MINIO_ADDRESS: minio-milvus:9000 MINIO_ACCESS_KEY_ID: ** MINIO_SECRET_ACCESS_KEY: ** volumes: - ./data/milvus:/var/lib/milvus ports: - 19530:19530 depends_on: - etcd - minio-milvus2.2 服务启动与初始化验证执行以下命令一键完成所有基础设施启动、状态校验和资源初始化# 1. 后台启动所有容器服务 docker-compose up -d # 2. 查看所有服务运行状态确认无异常退出 docker-compose ps # 3. 初始化业务MinIO存储桶用于存放旅游文档图片 docker exec -it kb-minio mc alias set myminio http://localhost:9000 ** ** docker exec -it kb-minio mc mb myminio/knowledge-images 核心踩坑提示MinerU 依赖 PyTorch、大量模型权重文件容器打包后镜像体积超20GB部署效率极低且兼容性差。生产环境强制建议宿主机直接安装运行MinerU通过子进程调用执行无需容器化。若需容器部署需单独构建GPU版本MinerU镜像。三、配置治理.env 统一管控彻底消除硬编码开发阶段代码中散落大量IP、端口、密钥、模型路径等硬编码参数不仅维护困难部署迁移时需要逐行修改极易出错。生产级项目规范所有可变配置统一由 .env 文件管理代码零硬编码通过python-dotenv统一读取实现一套配置适配多环境。在项目根目录新建.env全局配置文件整合所有服务参数# 大模型LLM全局配置 OPENAI_API_BASEhttps://api.openai.com/v1 OPENAI_API_KEY** MODELgpt-4o-mini VL_MODELgpt-4o # 多模态图片摘要模型 ITEM_MODELgpt-4o-mini # BGE向量模型本地路径 BGE_M3_PATH/data/models/BAAI/bge-m3 BGE_RERANKER_LARGE/data/models/BAAI/bge-reranker-v2-m3 BGE_RERANKER_DEVICEcpu # Milvus向量数据库配置 MILVUS_URLhttp://localhost:19530 CHUNKS_COLLECTIONtravel_content ITEM_NAME_COLLECTIONtravel_name EMBEDDING_DIM1024 # MongoDB会话数据库配置 MONGO_URLmongodb://**:**localhost:27017 MONGO_DB_NAMEknowledge_base # 业务MinIO对象存储配置 MINIO_ENDPOINTlocalhost:9000 MINIO_ACCESS_KEY** MINIO_SECRET_KEY** MINIO_BUCKET_NAMEknowledge-images # Redis任务缓存配置 REDIS_URLredis://localhost:6379/0 # 阿里MCP联网搜索配置 MCP_DASHSCOPE_BASE_URLhttps://dashscope.aliyuncs.com/api/v1/mcp按照同样逻辑改造查询模块、工具类的所有配置文件实现一处修改、全局生效。四、架构演进一Redis 替换内存字典解决状态丢失问题4.1 原生内存存储核心痛点前两篇教程中我们通过 Pythondefaultdict内存字典存储任务运行状态仅适用于单进程、临时开发场景生产环境存在两大致命缺陷服务重启数据清零迭代代码、重启FastAPI服务后所有正在执行的导入任务、进度状态全部丢失前端进度页直接失效多进程数据不共享生产环境使用Gunicorn多Worker部署时每个进程独立拥有内存字典前端轮询请求随机分发到不同进程出现进度数据为空、状态错乱问题。4.2 生产级解决方案使用Redis 缓存中间件替代本地内存存储利用Redis的跨进程共享、持久化、TTL过期特性实现任务状态统一管控彻底解决状态丢失、错乱问题。新建front/utils/task_util_redis.py完整替换原生任务状态工具类# front/utils/task_util_redis.py import json import redis from typing import List, Dict, Optional from dotenv import load_dotenv import os # 加载全局环境变量 load_dotenv() # 初始化线程安全的Redis连接 redis_client redis.Redis.from_url( os.getenv(REDIS_URL, redis://localhost:6379/0), decode_responsesTrue, # 自动字节转字符串简化数据处理 socket_connect_timeout5, ) # 任务状态缓存过期时间1小时自动清理老旧无效任务避免缓存堆积 TASK_TTL 3600 # 节点中英文映射与前端、原有逻辑完全对齐无感知替换 _NODE_NAME_TO_CN { import_file: 文件类型检测, pdf_to_md: PDF转Markdown, remake_img: Markdown图片处理, split_doc: 文档切分, extract_name: 商品名识别, query_analysis: 问题理解与重写, vector_search: 切片向量检索, hyde_search: 假设性文档检索, web_search: 联网搜索, rrf_search: 倒排融合排序, reranker_search: 重排序, answer_output: 生成答案, __end__: 处理完成, } def _to_cn(node_name: str) - str: 节点名中英文转换 return _NODE_NAME_TO_CN.get(node_name, node_name) def _get_task_key(task_id: str, suffix: str) - str: 统一Redis key命名规范便于管理 return ftask:{task_id}:{suffix} def add_running_task(task_id: str, node_name: str) - None: 标记节点为运行中状态Set结构自动去重 key _get_task_key(task_id, running) redis_client.sadd(key, node_name) redis_client.expire(key, TASK_TTL) def add_done_task(task_id: str, node_name: str) - None: 节点执行完成移出运行列表加入完成列表Redis管道保证原子性 running_key _get_task_key(task_id, running) done_key _get_task_key(task_id, done) pipe redis_client.pipeline() pipe.srem(running_key, node_name) pipe.sadd(done_key, node_name) pipe.expire(done_key, TASK_TTL) pipe.execute() def get_running_task_list(task_id: str) - List[str]: 获取当前运行中的节点列表 members redis_client.smembers(_get_task_key(task_id, running)) return [_to_cn(m) for m in members] def get_done_task_list(task_id: str) - List[str]: 获取已完成的节点列表 members redis_client.smembers(_get_task_key(task_id, done)) return [_to_cn(m) for m in members] def update_task_status(task_id: str, status: str) - None: 更新任务整体状态processing/completed/failed key _get_task_key(task_id, status) redis_client.setex(key, TASK_TTL, status) def get_task_status(task_id: str) - str: 获取任务整体状态 status redis_client.get(_get_task_key(task_id, status)) return status or def get_task_info(task_id: str) - Dict: 整合返回前端所需的完整任务信息 return { status: get_task_status(task_id), done_list: get_done_task_list(task_id), running_list: get_running_task_list(task_id), }4.3 迁移落地说明只需修改front/service/task_service.py的导入路径将原有内存工具类替换为Redis版本前端零适配、业务逻辑零改动即可实现状态持久化、多进程共享。五、架构演进二Celery 替换 BackgroundTasks实现长任务高可用5.1 原生后台任务的致命缺陷FastAPI 自带的BackgroundTasks仅适用于秒级轻量后台任务完全不适配本项目的文档导入场景旅游PDF文档解析、多模态图片摘要、向量入库属于分钟级长耗时任务FastAPI服务重启、进程崩溃、代码迭代时所有后台任务会直接终止、无法恢复不支持任务队列、并发管控、失败重试高并发场景极易任务堆积、丢失。5.2 生产级解决方案引入Celery 分布式任务队列搭配Redis作为消息中间件将所有长耗时导入任务剥离出Web服务主线程由独立Worker进程托管执行实现任务持久化、可追溯、不丢失、可并发管控。5.3 安装依赖pip install celery redis5.4 初始化Celery全局应用项目根目录新建celery_app.py统一配置任务队列参数# celery_app.py import os from celery import Celery from dotenv import load_dotenv # 加载环境变量 load_dotenv() # 初始化Celery应用Redis作为消息代理和结果存储 celery_app Celery( knowledge_base, brokeros.getenv(REDIS_URL, redis://localhost:6379/0), backendos.getenv(REDIS_URL, redis://localhost:6379/0), ) # 全局任务配置 celery_app.conf.update( task_serializerjson, accept_content[json], result_serializerjson, timezoneAsia/Shanghai, enable_utcTrue, task_track_startedTrue, # 开启任务状态追踪 task_time_limit1800, # 单任务最大执行时长30分钟防止卡死 ) # 自动发现项目内所有Celery任务 celery_app.autodiscover_tasks([processor.import_model, processor.search_model])5.5 改造导入流水线为Celery任务在导入模块新建processor/import_model/tasks.py将原有LangGraph流水线封装为异步任务# processor/import_model/tasks.py from celery_app import celery_app from processor.import_model.import_main_graph import run_import_pipeline from front.utils.task_util_redis import update_task_status, add_done_task celery_app.task(bindTrue, nameimport_pipeline) def run_import_pipeline_task(self, task_id: str, origin_path: str, origin_name: str): 异步执行旅游文档导入全流水线 :param task_id: 前端唯一任务ID :param origin_path: 上传文件本地路径 :param origin_name: 文件名 :return: 任务执行结果 try: # 更新任务为处理中状态 update_task_status(task_id, processing) # 执行完整LangGraph导入流水线 run_import_pipeline( task_idtask_id, origin_path_or_urlorigin_path, origin_file_nameorigin_name, ) # 任务执行完成更新状态 update_task_status(task_id, completed) add_done_task(task_id, __end__) return {status: completed, task_id: task_id} except Exception as e: # 异常兜底标记任务失败 update_task_status(task_id, failed) self.update_state(stateFAILURE, meta{error: str(e)}) raise e5.6 改造FastAPI路由切换异步任务入口修改文件上传路由移除原生后台任务改为提交Celery异步任务# import_router.py from celery_app import celery_app router.post(/upload, response_modelUploadResponse) async def upload_file( file: UploadFile File(...), service: ImportFileService Depends(get_import_file_service) ): # 同步保存上传文件原有逻辑不变 task_id, file_dir, import_file_path service.process_upload_file(file) # 提交Celery异步任务立即返回task_id不阻塞前端 celery_app.send_task( import_pipeline, args[task_id, import_file_path, Path(import_file_path).stem], task_idtask_id, # 自定义任务ID与前端轮询ID对齐 ) return UploadResponse(message上传文件成功, task_idtask_id)5.7 启动Celery Worker# 启动2并发Worker进程处理导入任务队列 celery -A celery_app worker -l info -c 2 架构升级核心收益改造完成后无论重启多少次FastAPI服务后台文档导入任务都会持续执行任务状态永久保存在Redis中前端进度展示完全不受影响真正实现无人值守后台任务。六、统一入口Nginx 反向代理彻底解决跨域与端口混乱当前项目存在两个独立后端服务端口分散、前端适配繁琐、存在跨域风险8000端口文档导入服务8001端口智能问答查询服务生产环境通过Nginx 反向代理统一收敛至80端口通过路径区分服务屏蔽后端端口细节彻底消除跨域问题同时优化SSE流式传输、大文件上传能力。6.1 Nginx生产级配置新建nginx.conf配置文件server { listen 80; server_name localhost; # 前端静态资源访问 location /front/ { alias /path/to/your/project/front/; try_files $uri $uri/ 404; } # 文档导入服务反向代理 location /api/import/ { proxy_pass http://127.0.0.1:8000/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # 适配大文件上传 client_max_body_size 60M; proxy_read_timeout 300s; } # 问答查询服务反向代理适配SSE流式传输 location /api/query/ { proxy_pass http://127.0.0.1:8001/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # 关闭缓冲保证SSE逐字推送生效 proxy_buffering off; proxy_cache off; proxy_read_timeout 600s; chunked_transfer_encoding off; } # 根路径默认跳转聊天页面 location / { return 302 /front/chat.html; } }6.2 前端接口地址动态适配修改前端HTML页面接口地址自动适配开发环境与生产Nginx环境无需手动切换const API_BASE (() { // 生产环境适配Nginx代理路径 if (window.location.pathname.includes(/front/)) { return /api/query; } // 开发环境保留原生端口访问 const host window.location.hostname; const port window.location.port || 80; return http://${host}:${port}; })();七、全链路端到端联调完成所有架构改造与部署配置后我们按规范顺序启动所有服务完成从文档上传、解析入库、智能问答的全流程闭环测试。7.1 服务启动顺序生产标准流程# 1. 启动所有Docker基础设施 docker-compose up -d # 2. 启动Celery异步任务队列独立终端 celery -A celery_app worker -l info -c 2 # 3. 启动文档导入服务独立终端 uvicorn import_router:create_app --host 0.0.0.0 --port 8000 --reload # 4. 启动智能问答服务独立终端 uvicorn query_router:create_app --host 0.0.0.0 --port 8001 --reload # 5. 启动Nginx代理服务 nginx -c /path/to/nginx.conf7.2 导入流程全链路验证访问http://localhost/front/import.html上传旅游攻略PDF文档Celery终端会实时打印流水线执行日志依次执行文件校验、PDF转MD、图片处理、文档切片、实体入库全流程前端进度条实时同步节点状态。7.3 问答SSE流式效果验证访问http://localhost/front/chat.html输入旅游相关问题浏览器开发者工具可捕获标准SSE事件流实现逐字打字机效果包含进度更新、增量文本、最终结果三类事件完全适配生产交互场景。八、性能耗时分析与生产优化方案8.1 文档导入流程耗时分布100页标准旅游PDF执行阶段耗时(秒)耗时占比性能说明MinerU PDF解析OCR45~6070%全局性能瓶颈CPU密集型任务多模态图片摘要生成15~2020%依赖大模型接口响应速度BGE向量化Milvus入库5~88%性能稳定无优化空间旅游实体抽取2~32%耗时可忽略核心优化方向MinerU为全局性能瓶颈生产环境可升级GPU版本、独立部署为微服务避免阻塞主业务流程。8.2 智能问答流程耗时分布执行阶段耗时(毫秒)优化建议问题重写与意图分析800~1200替换轻量模型qwen-turbo耗时可压缩至300ms内HyDE假设文档生成600~1000高频问题缓存结果减少重复调用Milvus混合检索50~80性能优异无需优化联网搜索结果融合排序300~600可配置搜索缓存策略大模型流式答案生成3000~5000依赖模型本身可通过模型降级优化九、生产落地高频踩坑实录与解决方案9.1 MinerU模型加载失败报错现象子进程调用mineru提示模型文件不存在、下载超时根因国内无法直接访问Hugging Face官方源模型下载失败解决方案全局配置HF国内镜像指定模型本地缓存目录import os os.environ[HF_ENDPOINT] https://hf-mirror.com os.environ[HF_HOME] /data/models9.2 Milvus向量维度不匹配报错现象向量入库提示dimension mismatch: expected 1024, got 768解决方案统一BGE-M3向量维度为1024核对Milvus集合初始化dim参数保持全局一致。9.3 SSE流式响应一次性返回无逐字效果根因Nginx默认开启响应缓冲导致流式数据被缓存合并解决方案在查询服务代理配置中强制关闭缓冲前文Nginx配置已内置该方案。9.4 Celery启动报模块不存在解决方案启动前将项目根目录加入Python环境变量export PYTHONPATH$(pwd)十、系列终章总结10.1 本篇核心成果本篇作为系列收官之作完成了旅游RAG系统从开发原型到生产可用的全方位升级补齐了系统落地的最后短板容器化部署Docker Compose一键搭建全量基础设施抹平环境差异配置规范化.env全局配置管控彻底消除代码硬编码架构高可用升级Redis持久化任务状态、Celery托管长耗时任务解决服务重启、多进程部署的核心痛点网关统一优化Nginx反向代理收敛端口解决跨域问题适配SSE流式传输全链路验证完成从文档入库到智能问答的端到端测试汇总性能优化与踩坑方案。10.2 系列整体复盘本系列三篇教程完整闭环前端交互→后端算法→生产部署的全链路开发流程上篇打磨前端交互细节实现极致用户体验中篇拆解LangGraph双流水线落地混合检索、多模态解析核心AI能力下篇重构系统架构、标准化部署流程实现生产级稳定落地。这套开源RAG骨架完全通用你可以基于现有代码快速改造替换旅游知识库为法律、医疗、企业文档、教育资料等垂直场景快速落地专属私有化知识库系统。技术深耕行则将至。本系列教程正式完结希望这套实战化落地方案能帮助每一位后端/AI初学者真正吃透RAG全链路开发与部署