# 线上部署与数据导入完整操作方案 > **适用环境**: Linux 生产服务器(当前: `iZwz92tgv6q223rdi4w8cdZ`) > **项目路径**: `/opt/pharmacopoeia-ai` > **药典数据源**: `/opt/2025`(6317 个 DOCX 文件) > **耗时**: 首次完整部署约 2-4 小时(主要在 DOCX 向量化) --- ## 一、环境检查与代码拉取 ```bash # ============================================================ # 1.1 基础环境确认 # ============================================================ java -version 2>&1 # 期望: 21.x.x(若未安装需先装 JDK 21) python3 --version # 期望: 3.10+ git --version # 基本命令 # ============================================================ # 1.2 拉取最新代码 # ============================================================ cd /opt/pharmacopoeia-ai git pull origin main git status # 期望: 无冲突,干净状态(或有新增文件) # ============================================================ # 1.3 创建必要目录 # ============================================================ mkdir -p /var/log/pharmacopoeia mkdir -p /opt/pharmacopoeia-ai/backend-java/target # ============================================================ # 1.4 配置环境变量(如首次部署) # ============================================================ cd /opt/pharmacopoeia-ai if [ ! -f .env ]; then cp .env.example .env echo ">>> 请编辑 .env 文件,填入 QWEN_API_KEY 等真实值 <<<" fi # 确认关键配置已填写 grep -E "QWEN_API_KEY|POSTGRES_PASSWORD" .env # QWEN_API_KEY=sk-your-real-key ← 必须是有效值 # POSTGRES_PASSWORD=pharma2025 ``` --- ## 二、编译 Java 后端 ```bash cd /opt/pharmacopoeia-ai/backend-java # 2.1 设置 JDK 21 export JAVA_HOME=/usr/lib/jvm/jdk-21 # 如果不知道 JDK 路径,用 update-alternatives 查找: # update-alternatives --list java # 2.2 编译打包 mvn clean package -DskipTests -q # 确认 jar 包生成 ls -lh target/pharmacopoeia-ai-1.0.0.jar # 期望: ~50MB jar 文件 ``` --- ## 三、启动基础设施(PostgreSQL + Redis) ```bash cd /opt/pharmacopoeia-ai/deploy # 3.1 拉取镜像并启动 docker-compose pull docker-compose up -d # 3.2 等待健康检查通过 echo "等待 PostgreSQL 就绪..." sleep 15 docker-compose ps # pharmacopoeia-pg Up (healthy) # pharmacopoeia-redis Up (healthy) # 3.3 验证 PG 连接 docker exec pharmacopoeia-pg pg_isready -U postgres # /var/run/postgresql:5432 - accepting connections ``` --- ## 四、初始化数据库 ```bash cd /opt/pharmacopoeia-ai # ============================================================ # 4.1 【首次部署 或 Schema 变更时】完全重置数据库 # 警告:这会删除所有旧数据,之后必须重新导入 # ============================================================ docker exec -i pharmacopoeia-pg psql -U postgres -d pharmacopoeia < database/reset_schema.sql # 4.2 导入最新表结构 docker exec -i pharmacopoeia-pg psql -U postgres -d pharmacopoeia < database/schema.sql # ============================================================ # 4.3 【如果是旧库升级,不想丢数据】仅执行迁移 # ============================================================ # docker exec -i pharmacopoeia-pg psql -U postgres -d pharmacopoeia < database/migrate_json_to_jsonb.sql # 4.4 验证表结构 docker exec pharmacopoeia-pg psql -U postgres -d pharmacopoeia -c "\dt" # 期望 9 张表 --- ## 五、安装 Python 依赖 ```bash cd /opt/pharmacopoeia-ai/data-pipeline # 5.1 创建虚拟环境(只需一次) python3 -m venv venv # 5.2 激活虚拟环境并安装依赖 source venv/bin/activate pip install httpx sqlalchemy asyncpg psycopg2-binary python-docx # 5.3 验证 python -c "import httpx, sqlalchemy, docx; print('OK')" # ⚠️ 之后每次执行 data-pipeline 脚本前,都需要先激活 venv: # source /opt/pharmacopoeia-ai/data-pipeline/venv/bin/activate ``` --- ## 六、导入 Wiki 临床数据(快速,~2 分钟) **数据内容**: 13 个药品的维基百科临床专著(概述/适应症/药理/不良反应等)+ 4 个药典示例 + 4 个用药指导 ```bash cd /opt/pharmacopoeia-ai/data-pipeline # 激活虚拟环境 source venv/bin/activate # 6.1 加载环境变量 set -a source ../.env set +a # 6.2 执行导入 python import_all.py ``` **预期输出**: ``` 📂 扫描数据目录: .../data-pipeline/data ✅ sample_drugs.json — 兼容,将导入 ✅ wiki_merged.json — 兼容,将导入 ✅ drug_guides.json — 兼容,将导入 ⏭️ drug_index.json — 跳过 ⏭️ catalog_volume1.json — 跳过 ... 📦 共 3 个文件待导入 🚀 正在导入: sample_drugs.json ... 🎉 全部导入完成! ``` **验证**: ```bash docker exec pharmacopoeia-pg psql -U postgres -d pharmacopoeia -c " SELECT COUNT(*) AS drugs FROM drugs WHERE is_active=TRUE; SELECT COUNT(*) AS chunks FROM drug_chunks WHERE vec IS NOT NULL; " # drugs: ~21, chunks: ~200 ``` --- ## 七、导入药典 DOCX 原文(完整,~2-4 小时) **数据内容**: `/opt/2025/` 下 6317 个 DOCX 文件(2025 年版中国药典四部全文) ```bash cd /opt/pharmacopoeia-ai/data-pipeline # 激活虚拟环境 source venv/bin/activate # 7.1 加载环境变量(如果上面已做可跳过) set -a source ../.env set +a # 7.2 确认数据源 ls /opt/2025/output2/品种正文/*.docx | wc -l # 期望: 2930(二部化学药最多) # 7.3 在 screen 中运行(防止 SSH 断连中断) screen -S docx-ingest # screen 内执行以下命令: cd /opt/pharmacopoeia-ai/data-pipeline source venv/bin/activate set -a source ../.env set +a # 执行导入(默认路径 /opt/2025) python docx_ingest.py # Ctrl+A D 分离 screen # screen -r docx-ingest 重新连接查看进度 ``` **进度监控**(另开终端): ```bash # 每 60 秒查看入库进度 watch -n 60 "docker exec pharmacopoeia-pg psql -U postgres -d pharmacopoeia -t -c 'SELECT NOW() AS time, COUNT(*) AS chunks FROM drug_chunks;'" ``` **预期结果**: ``` 📂 扫描 DOCX 文件... 发现 6317 个 DOCX 文件 📦 解析完成: ~6300 个有效条目 分类分布: 化学药: 2930 中药: 2276 通则: 689 药用辅料: 387 ... 🎉 全部完成!新增药品 ~6300 个, chunks ~35000 条 ``` --- ## 八、启动 Java 后端服务 ```bash cd /opt/pharmacopoeia-ai/backend-java # 8.1 设置环境变量 export POSTGRES_PASSWORD=$(grep POSTGRES_PASSWORD /opt/pharmacopoeia-ai/.env | cut -d= -f2) export QWEN_API_KEY=$(grep QWEN_API_KEY /opt/pharmacopoeia-ai/.env | cut -d= -f2) # 8.2 启动服务 nohup java -Xms512m -Xmx2g -Dfile.encoding=UTF-8 \ -jar target/pharmacopoeia-ai-1.0.0.jar \ > /var/log/pharmacopoeia/backend.log 2>&1 & # 8.3 等待启动 sleep 10 # 8.4 验证 curl -s http://localhost:9000/api/v1/health # {"status":"UP"} curl -s http://localhost:9000/api/v1/admin/stats | python3 -m json.tool # {"total_drugs": ~6300, "total_chunks": ~35000, ...} ``` --- ## 九、验证搜索功能 ```bash # 9.1 药品搜索 curl -s "http://localhost:9000/api/v1/drug/search?keyword=布洛芬" | python3 -m json.tool | head -20 # 9.2 AI 问答 curl -s -X POST http://localhost:9000/api/v1/chat/ask \ -H "Content-Type: application/json" \ -d '{"message":"布洛芬缓释胶囊的用法用量"}' | python3 -m json.tool | head -30 # 9.3 分类树 curl -s http://localhost:9000/api/v1/drug/category/tree | python3 -m json.tool | head -15 # 9.4 Wiki 数据(临床专著) curl -s "http://localhost:9000/api/v1/drug/search?keyword=甲硝唑" | python3 -m json.tool | head -15 ``` --- ## 十、设置开机自启(可选) ```bash # 10.1 创建 systemd 服务 cat > /etc/systemd/system/pharmacopoeia.service << 'SERVICEOF' [Unit] Description=Pharmacopoeia AI Backend After=network.target docker.service Requires=docker.service [Service] Type=simple User=root WorkingDirectory=/opt/pharmacopoeia-ai/backend-java EnvironmentFile=/opt/pharmacopoeia-ai/.env ExecStart=/usr/lib/jvm/jdk-21/bin/java -Xms512m -Xmx2g -Dfile.encoding=UTF-8 -jar target/pharmacopoeia-ai-1.0.0.jar Restart=always RestartSec=10 StandardOutput=append:/var/log/pharmacopoeia/backend.log StandardError=append:/var/log/pharmacopoeia/backend-error.log [Install] WantedBy=multi-user.target SERVICEOF # 10.2 启用 systemctl daemon-reload systemctl enable pharmacopoeia systemctl start pharmacopoeia systemctl status pharmacopoeia # 10.3 Docker 容器也设置自启 cd /opt/pharmacopoeia-ai/deploy # 已在 docker-compose.yml 中默认 restart: (无), # 可加 restart: always 后 docker-compose up -d 生效 ``` --- ## 十一、故障排查 ### PG 连接失败 ```bash docker logs pharmacopoeia-pg --tail 30 docker start pharmacopoeia-pg ``` ### Java 启动失败 ```bash tail -50 /var/log/pharmacopoeia/backend-error.log # 常见: PG 未启动 → 检查 Step 三 # 常见: API Key 无效 → 检查 .env 中的 QWEN_API_KEY ``` ### DOCX 导入中断 ```bash # 直接重新运行即可(ON CONFLICT DO NOTHING,不重复写入) screen -r docx-ingest # 如果 screen 已丢失,重新执行 Step 七 ``` ### 搜索无结果 ```bash # 确认数据状态 docker exec pharmacopoeia-pg psql -U postgres -d pharmacopoeia -c " SELECT 'drugs' AS tbl, COUNT(*) FROM drugs WHERE is_active=TRUE UNION ALL SELECT 'chunks', COUNT(*) FROM drug_chunks WHERE vec IS NOT NULL; " # drugs 和 chunks 都应为 >0 ``` --- ## 十二、完全重导数据(含图片提取) > 适用:DOCX 解析逻辑更新、图片提取功能上线、数据清空重建 ```bash cd /opt/pharmacopoeia-ai # 1. 停 Java bash tools/java-deploy.sh stop # 2. 清空旧数据 docker exec -i pharmacopoeia-pg psql -U postgres -d pharmacopoeia -c " TRUNCATE drug_chunks CASCADE; TRUNCATE drugs CASCADE; " # 3. 重建表结构 docker exec -i pharmacopoeia-pg psql -U postgres -d pharmacopoeia < database/schema.sql # 4. 创建图片目录 mkdir -p static/images/drugs # 5. 导入 Wiki(~2 分钟) cd data-pipeline && source venv/bin/activate python import_all.py # 6. 导入 2025 药典 DOCX(~2-4 小时,含图片提取) screen -S reimport python docx_ingest.py # 7. 跑完后验证 python verify_import.py # 8. 修复 vec 列 docker exec -i pharmacopoeia-pg psql -U postgres -d pharmacopoeia -c " UPDATE drug_chunks SET vec = (embedding::text)::vector WHERE vec IS NULL AND embedding IS NOT NULL; " # 9. 重启 Java cd /opt/pharmacopoeia-ai && bash tools/java-deploy.sh restart && nginx -s reload ``` --- ## 快速参考 | 路径/命令 | 用途 | |-----------|------| | `/opt/pharmacopoeia-ai/` | 项目根目录 | | `/opt/2025/` | DOCX 药典数据源 | | `/opt/pharmacopoeia-ai/static/images/drugs/` | DOCX 提取的图片 | | `docker-compose ps` | 查看 PG/Redis 状态 | | `screen -r reimport` | 重连重导任务 | | `http://localhost:9000/api/v1/health` | 健康检查 | | `/var/log/pharmacopoeia/backend.log` | Java 日志 |