AstroResearch/docs/deployment.md
Asfmq 3f1935678b feat: LLM/Embedding 客户端模块化、侧边栏折叠交互、arXiv→ADS 下载回退与前端体验重构
**后端架构**
  - 抽取翻译服务中内嵌的 LLM HTTP 调用为独立的 LlmClient /
    EmbeddingClient(src/clients/llm.rs),翻译模块改为委托调用,消除
    对 reqwest/serde 的直接耦合
  - Config 新增 EMBEDDING_API_KEY/EMBEDDING_API_BASE/EMBEDDING_MODEL
    三项配置,默认 fallback 至 LLM 对应值,补齐向量嵌入基础设施

  **下载策略优化**
  - arXiv 直连下载失败后自动回退至 ADS 网关 PUB_PDF→EPRINT_PDF→CrossRef
    多级通道,替换此前单路径策略;批量同步同步应用此逻辑
  - PDF/HTML 任一方成功时,失败方的 path 字段不再存储 "error:" 报错字符串,
    改为置 NULL,防止日志污染数据

  **前端交互增强**
  - 侧边栏支持折叠/展开:收起为仅图标模式(w-16),展开恢复完整模式(w-64);
    收起后点击 Logo 展开,含流畅 cubic-bezier 过渡动画
  - 阅读面板新增 PDF 内嵌预览:已下载 PDF 时可通过 iframe 切换查看
    /api/files 下的本地文献
  - reader/citation 面板未选文献时展示带图标的空状态引导页,替代空白页
  - 文献详情面板改为固定高度弹性布局(h-[460px]),各区块按比例分配避免
    内容挤压;期刊名过长截断+悬停tooltip;关键词无数据显式占位
  - 全局移除 emoji Unicode,统一替换为 lucide-react 图标组件,
    消除跨平台字体渲染差异

  **反爬检测精细化**
  - 按响应长度分层:>150KB 跳过检测(完整文献),<5KB 才扫描通用 HTTP
    错误关键字,杜绝长文献误触 Cloudflare/503 模式匹配
  - 新增 Radware Bot Manager、ShieldSquare WAF 特征识别

  **健壮性**
  - Obscura 下载校验失败后自动清理硬盘残留坏文件
  - 健康检查工具:文献已有有效 HTML 但 PDF 字段为旧报错时自动判定可修复
  - 上传接口 body limit 提升至 100MB,新增 /api/files 静态文件服务路由
  - StandardPaper 新增 has_pdf/has_html 字段区分格式级下载状态
2026-06-13 11:11:33 +08:00

176 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# AstroResearch Deployment Guide / 部署指南
AstroResearch 的后端服务是由 Rust 编译出的单执行文件,它内置托管了前端 React 的静态构建资源,因此生产部署十分简单。
---
## 1. 系统要求与环境依赖 (Requirements)
- **操作系统**Linux / macOS / Windows
- **运行环境**
- Node.js (v18+) 用以构建前端 React 资源
- Rust (1.75+) 用以编译后端 Axum 进程
- SQLite (自动内置,无需单独部署)
---
## 2. 生产构建步骤 (Production Build Steps)
### 步骤 1构建 React 前端静态资源
进入 `dashboard` 文件夹,安装依赖并执行编译命令。编译产物会自动输出在 `dashboard/dist` 目录下:
```bash
cd dashboard
npm install
npm run build
```
### 步骤 2编译 Rust 后端二进制文件
返回项目根目录,通过 Cargo 构建 Release 版本的执行文件。编译后的程序会内置链接 `dashboard/dist` 下的全部静态资源:
```bash
cd ..
cargo build --release
```
编译产物位于 `target/release/astroresearch`
### 步骤 3可选编译健康检查工具
如需在目标服务器上运行馆藏健康度诊断与修复:
```bash
cargo build --release --bin health_check
```
编译产物位于 `target/release/health_check`
---
## 3. 服务部署与启动 (Running in Production)
1. 将编译出来的 `target/release/astroresearch` 二进制文件部署到目标服务器。
2. 在二进制文件同一目录下,创建并填写 `.env` 环境变量配置文件(可从根目录的 `.env.example` 复制模板)。
3. 确保本地相对路径下拥有天文对照词典文件 `dictionary.txt`
4. 运行后端服务:
```bash
./astroresearch
```
5. 进程将默认在后台启动并监听 `http://localhost:8000` 端口。你可以通过 Nginx 将此端口反向代理到公网 80/443 端口。
---
## 4. Obscura 两种抓取后备部署模式选择 (Obscura Deployment Modes)
系统集成了 `Obscura` 无头浏览器框架来作为遭遇 WAF/Cloudflare 反爬时的自动后备抓取通道。系统支持以下两种编译与部署模式:
### 模式 A外部命令行模式 (默认,推荐)
该模式将主 Web 服务与 V8 浏览器运行引擎相隔离,最适合常规生产环境。它拥有最快的编译时间,且进程隔离确保无头浏览器内核异常(如 OOM 或 Panic不会拖垮主服务器。
1. **编译主服务**
```bash
cargo build --release
```
2. **下载/配置外部二进制**
从 GitHub Releases 下载编译好的 `obscura-x86_64-linux.tar.gz` 压缩包,解压后将 `obscura``obscura-worker` 两个二进制文件放到项目根目录的 `bin/` 目录下:
```bash
mkdir -p bin/
# 放入 bin/obscura 和 bin/obscura-worker并赋予执行权限
chmod +x bin/obscura bin/obscura-worker
```
3. **运行**
```bash
./target/release/astroresearch
```
当遭遇 WAF 拦截时,主进程将自动通过异步子进程调用 `./bin/obscura` 进行抓取。
### 模式 B进程内集成模式 (In-Process Feature)
该模式将整个无头浏览器及 V8 运行引擎直接静态链接编译进单个二进制文件中。这免去了在服务器分发和配置外部可执行程序的步骤,提供了“零配置”的部署体验。
> [!WARNING]
> 由于需要静态链接 C++ 编写的 V8 引擎,**首次编译会额外多耗时 1 到 3 分钟**,且最终编译生成的**单体可执行文件体积会膨胀约 80MB**。
1. **启用 Feature 编译**
在构建时指定 `--features obscura-inprocess` 特性标记:
```bash
cargo build --release --features obscura-inprocess
```
2. **运行**
```bash
./target/release/astroresearch
```
主服务运行期间,无需在磁盘中放置任何 `bin/obscura` 二进制。当触发反爬时,系统会在后台的专有阻塞线程池上通过独立包装的单线程 runtime 驱动进程内 V8 浏览器内核直接抓取。
---
## 5. 极致内存与体积优化部署 (Ultra-Low Memory & Size Optimization)
对于运行在低配/低内存服务器(如 1核512M 或 1核1G 实例)的环境,系统内置了可选的编译与运行时优化策略。
> [!NOTE]
> 极致内存与体积优化编译配置(`release-min`)和“进程内集成模式 (In-Process Feature)”在**技术上可以完全兼容并共同启用**,但它们在**优化目标(指标)上是相互抵消(矛盾)的**。
> 如果启用了进程内 V8 特性C++ 静态链接库本身占用的 80MB+ 空间将无法被剔除,导致无法达成极致轻量化(~8.3MB)的体积指标;且 V8 运行时堆内存也会带来额外的物理内存开销。因此,为追求极致低资源消耗,建议在低配服务器上采用**“模式 A外部命令行模式”**。
>
> 如果你执意要在**进程内浏览器集成下尽可能对其体积和依赖进行优化**,可以组合使用 `--profile` 与 `--features` 参数进行编译和运行:
> ```bash
> # 编译并打包优化后的进程内单二进制文件:
> cargo build --profile release-min --features obscura-inprocess
>
> # 编译并直接运行:
> cargo run --profile release-min --features obscura-inprocess
> ```
### 优化指标对比:
* **二进制执行文件大小**:由 `17.0 MB` 压缩至 **`8.3 MB`**(缩减约 51%)。
* **启动物理常驻内存 (RSS)**:由 `34.8 MB` 降至 **`32.9 MB`**(得益于词典加载后的容量自动收缩)。
* **虚拟内存 (VSZ)**:由 `1.27 GB` 降至 **`302 MB`**(缩减约 76%)。
* **数据段内存 (VmData)**:由 `60.1 MB` 降至 **`26.5 MB`**(缩减约 55%)。
### 部署优化步骤:
1. **使用优化 Profile 进行编译**
在项目根目录下,使用内置的 `release-min` 编译配置:
```bash
cargo build --profile release-min
```
编译完成后的执行文件位于 `target/release-min/astroresearch`。该配置开启了 LTO链接时优化、剥离了调试符号并在生成时进行了大小优化。
2. **限制运行时异步线程数**
默认情况下,异步运行时 Tokio 会根据系统的 CPU 核心数(例如 16 核)创建对应数量的 Worker 线程,这会带来很多虚拟/物理内存浪费。启动服务时,可通过注入 `TOKIO_WORKER_THREADS=1` 环境变量限制线程池大小:
```bash
PORT=8000 TOKIO_WORKER_THREADS=1 ./astroresearch
```
---
## 6. 环境变量配置 (Environment Variables)
| 变量名 | 必需 | 默认值 | 说明 |
| :--- | :--- | :--- | :--- |
| `DATABASE_URL` | 否 | `sqlite://library/astro_research.db` | SQLite 数据库连接 URL |
| `ADS_API_KEY` | 是 | - | NASA ADS API 访问 Token |
| `LLM_API_KEY` | 是 | - | 大语言模型 API Key |
| `LLM_API_BASE` | 否 | `https://api.openai.com/v1` | 大语言模型 API 基础地址 |
| `LLM_MODEL` | 否 | `gpt-4o-mini` | 翻译大模型名称 |
| `EMBEDDING_API_KEY` | 否 | 默认与 `LLM_API_KEY` 一致 | 向量模型 API Key |
| `EMBEDDING_API_BASE`| 否 | 默认与 `LLM_API_BASE` 一致 | 向量模型 API 基础地址 |
| `EMBEDDING_MODEL` | 否 | `text-embedding-3-small` | 向量模型名称 |
| `QINIU_AK` | 否 | - | 七牛云 Access Key |
| `QINIU_SK` | 否 | - | 七牛云 Secret Key |
| `QINIU_BUCKET` | 否 | - | 七牛云存储空间名 |
| `QINIU_DOMAIN` | 否 | - | 七牛云外链 CDN 域名 |
| `MINERU_API_URL` | 否 | - | MinerU PDF 解析远程 API 地址 |
| `MINERU_API_KEY` | 否 | - | MinerU API Token |
| `LIBRARY_DIR` | 否 | `./library` | 本地文献馆藏根目录 |
| `PORT` | 否 | `8000` | 后端服务监听端口 |
---
## 7. 健康检查与维护 (Health Check)
部署后可定期运行健康检查工具排查馆藏一致性问题:
```bash
# 只读扫描(不修改任何数据)
./health_check
# 自动修复(清理损坏文件、重置无效路径)
./health_check -- --fix
```
详见 [排障指南 §4.2](troubleshooting.md#42-馆藏文献健康度检查工具-health_check)。