Files
AIclinicalresearch/docs/02-通用能力层/06-R统计引擎/01-R统计引擎架构与部署指南.md

14 KiB
Raw Blame History

R 统计引擎架构与部署指南

版本: v1.0
创建日期: 2026-02-19
维护者: SSA-Pro 开发团队
状态: 生产就绪


📋 目录

  1. 概述
  2. 架构设计
  3. Docker 镜像构建
  4. 部署指南
  5. API 参考
  6. 开发指南
  7. 运维指南
  8. 常见问题

1. 概述

1.1 什么是 R 统计引擎

R 统计引擎是平台的专用统计计算服务,基于 Docker 容器化部署,提供:

  • 🧮 严谨的统计分析能力T 检验、方差分析、回归等)
  • 🛡️ 统计护栏(正态性检验、方差齐性检验等)
  • 📊 可视化输出Base64 编码的图表)
  • 📝 可复现代码生成APA 格式的 R 脚本)

1.2 定位

┌─────────────────────────────────────────────────────────────┐
│                      业务模块层                              │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐                     │
│  │ SSA-Pro │  │  其他   │  │  其他   │                     │
│  │ 智能统计 │  │  模块   │  │  模块   │                     │
│  └────┬────┘  └─────────┘  └─────────┘                     │
├───────┼─────────────────────────────────────────────────────┤
│       ▼           通用能力层                                 │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              R 统计引擎 (Docker)                     │   │
│  │  • /health         健康检查                          │   │
│  │  • /api/v1/tools   工具列表                          │   │
│  │  • /api/v1/skills  技能执行                          │   │
│  └─────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘

1.3 技术栈

组件 版本 说明
R 4.3.3 统计计算核心
plumber 1.2.1 REST API 框架
ggplot2 最新 数据可视化
car 3.1-2 高级统计检验
dplyr/tidyr 最新 数据处理
Docker 24+ 容器化部署

2. 架构设计

2.1 Brain-Hand 模型

R 统计引擎采用 Brain-Hand 分离架构

┌──────────────────┐          ┌──────────────────┐
│    Node.js       │          │    R Docker      │
│    (Brain)       │          │    (Hand)        │
├──────────────────┤          ├──────────────────┤
│ • 业务逻辑       │  HTTP    │ • 统计计算       │
│ • 认证鉴权       │ ───────> │ • 数据处理       │
│ • OSS 签名       │          │ • 图表生成       │
│ • 结果解释       │ <─────── │ • 代码生成       │
└──────────────────┘  JSON    └──────────────────┘

2.2 数据传输协议

支持两种数据传输方式:

方式 条件 字段
inline 数据 < 2MB data_source.data (JSON)
oss 数据 >= 2MB data_source.oss_url (预签名 URL)
// 方式 1: inline
{
  "data_source": {
    "type": "inline",
    "data": [{"group": "A", "value": 10}, ...]
  }
}

// 方式 2: oss (预签名 URL)
{
  "data_source": {
    "type": "oss",
    "oss_url": "https://bucket.oss.com/data.csv?signature=xxx"
  }
}

2.3 安全设计

安全措施 实现方式
非特权用户 USER appuser
路径遍历防护 tool_code 正则白名单 ^[A-Z][A-Z0-9_]*$
OSS 密钥隔离 Node.js 生成预签名 URLR 无需持有密钥
健康检查 Docker HEALTHCHECK

3. Docker 镜像构建

3.1 完整 Dockerfile

FROM rocker/r-ver:4.3

LABEL maintainer="dev-team@aiclinicalresearch.com"
LABEL version="1.0.1"
LABEL description="SSA-Pro R Statistics Service"

# 安装系统依赖(包括 R 包编译所需的库)
RUN apt-get update && apt-get install -y \
    libcurl4-openssl-dev \
    libssl-dev \
    libxml2-dev \
    libsodium-dev \
    zlib1g-dev \
    libnlopt-dev \
    liblapack-dev \
    libblas-dev \
    gfortran \
    pkg-config \
    cmake \
    curl \
    && rm -rf /var/lib/apt/lists/*

# 直接安装 R 包
RUN R -e "install.packages(c( \
    'plumber', \
    'jsonlite', \
    'ggplot2', \
    'glue', \
    'dplyr', \
    'tidyr', \
    'base64enc', \
    'yaml', \
    'car', \
    'httr' \
), repos='https://cloud.r-project.org/', Ncpus=2)"

# 安全加固:创建非特权用户
RUN useradd -m -s /bin/bash appuser

WORKDIR /app

# 复制应用代码
COPY plumber.R plumber.R
COPY utils/ utils/
COPY tools/ tools/
COPY tests/ tests/

# 设置目录权限
RUN chown -R appuser:appuser /app

# 切换到非特权用户
USER appuser

EXPOSE 8080

# 环境变量
ENV DEV_MODE="false"

# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:8080/health || exit 1

# 启动服务
CMD ["R", "-e", "plumber::plumb('plumber.R')$run(host='0.0.0.0', port=8080)"]

3.2 系统依赖说明

依赖包 用途
libcurl4-openssl-dev httr 包HTTP 请求)
libssl-dev openssl 包(加密)
libxml2-dev xml2 包XML 解析)
libsodium-dev sodium 包(加密)
zlib1g-dev httpuv 包Web 服务器)
libnlopt-dev nloptr 包(优化算法)
liblapack-dev 线性代数计算
libblas-dev 基础线性代数
gfortran Fortran 编译器(部分 R 包需要)
cmake nloptr 包构建
curl 健康检查

3.3 构建命令

# 本地构建
cd r-statistics-service
docker build -t ssa-r-statistics:1.0.1 .

# 查看镜像
docker images ssa-r-statistics

# 预期输出
REPOSITORY         TAG       IMAGE ID       CREATED         SIZE
ssa-r-statistics   1.0.1     xxxxxxxxxxxx   x minutes ago   1.81GB

3.4 构建时间参考

阶段 耗时
基础镜像下载 ~2 分钟(首次)
系统依赖安装 ~1 分钟
R 包安装 ~6 分钟
总计 ~9 分钟

4. 部署指南

4.1 开发环境

使用 docker-compose

# r-statistics-service/docker-compose.yml
version: '3.8'

services:
  ssa-r-service:
    build: .
    container_name: ssa-r-statistics
    ports:
      - "8082:8080"  # 主机8082 → 容器8080REDCap占用8080/8081
    environment:
      - DEV_MODE=true
    volumes:
      # 开发环境挂载:支持热重载
      - ./tools:/app/tools
      - ./utils:/app/utils
      - ./tests:/app/tests
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]  # 容器内部仍是8080
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s

启动命令:

cd r-statistics-service
docker-compose up -d

4.2 生产环境 (SAE)

# SAE 配置
容器镜像: registry.cn-beijing.aliyuncs.com/aiclinical/ssa-r-statistics:1.0.1
实例规格: 2 vCPU, 4 GB
最小实例: 1
最大实例: 5
端口: 8080

环境变量:
  DEV_MODE: "false"

4.3 环境变量

变量 默认值 说明
DEV_MODE false 开发模式(启用热重载,每次请求重新加载工具脚本)

说明:开发环境和生产环境都使用真实 OSS无需 Mock 数据。

  • 开发环境:ai-clinical-data-dev bucket
  • 生产环境:ai-clinical-data bucket

4.4 端口配置

环境 主机端口 容器端口 说明
开发环境 8082 8080 避免与 REDCap 8080/8081 冲突
生产环境 (SAE) 8080 8080 云端无端口冲突

注意Node.js 后端通过 R_SERVICE_URL 环境变量配置 R 服务地址,默认值为 http://localhost:8082


5. API 参考

5.1 健康检查

GET /health

响应:

{
  "status": "ok",
  "timestamp": "2026-02-19 08:00:00",
  "version": "1.0.1",
  "dev_mode": true,
  "tools_loaded": 1
}

5.2 工具列表

GET /api/v1/tools

响应:

{
  "status": "ok",
  "tools": ["t_test_ind", "anova_oneway"],
  "count": 2
}

5.3 执行技能

POST /api/v1/skills/{tool_code}
Content-Type: application/json

请求体:

{
  "data_source": {
    "type": "inline",
    "data": [...]
  },
  "params": {
    "group_var": "group",
    "value_var": "value"
  },
  "guardrails": {
    "check_normality": true
  }
}

成功响应:

{
  "status": "success",
  "message": "分析完成",
  "warnings": null,
  "results": {
    "method": "Welch Two Sample t-test",
    "statistic": -5.196,
    "df": 5.98,
    "p_value": 0.002,
    "p_value_fmt": "p = .002"
  },
  "plots": ["data:image/png;base64,..."],
  "trace_log": [...],
  "reproducible_code": "..."
}

错误响应:

{
  "status": "error",
  "error_code": "E001",
  "error_type": "business",
  "message": "列名 'xxx' 在数据中不存在",
  "user_hint": "请检查变量名是否拼写正确"
}

6. 开发指南

6.1 添加新工具

  1. tools/ 目录创建 R 脚本:
# tools/my_analysis.R

#' @tool_code ST_MY_ANALYSIS
#' @name 我的分析工具
#' @version 1.0.0

# 统一入口函数
run_analysis <- function(input) {
  # 加载数据
  df <- load_input_data(input)
  
  # 参数
  p <- input$params
  
  # 护栏检查
  # ...
  
  # 核心计算
  # ...
  
  # 返回结果
  return(list(
    status = "success",
    message = "分析完成",
    results = list(...)
  ))
}
  1. 重启服务(开发模式无需重启)

  2. 测试:

curl -X POST http://localhost:8082/api/v1/skills/ST_MY_ANALYSIS \
  -H "Content-Type: application/json" \
  -d '{"data_source": {...}, "params": {...}}'

6.2 工具命名规范

项目 规范
文件名 小写下划线:t_test_ind.R
tool_code 大写下划线:ST_T_TEST_IND
入口函数 固定名称:run_analysis

6.3 结果格式规范

return(list(
  status = "success" | "error" | "blocked",
  message = "...",
  warnings = c("...") | NULL,
  results = list(
    # 统计结果
  ),
  plots = list(
    "data:image/png;base64,..."
  ),
  trace_log = c("..."),
  reproducible_code = "..."
))

7. 运维指南

7.1 日志查看

# 实时日志
docker logs -f ssa-r-statistics

# 最近 100 行
docker logs --tail 100 ssa-r-statistics

7.2 性能监控

# 容器资源使用
docker stats ssa-r-statistics

7.3 重启服务

# 开发环境
docker-compose restart

# 生产环境 (SAE)
通过 SAE 控制台重启实例

7.4 镜像更新

# 1. 构建新镜像
docker build -t ssa-r-statistics:1.0.2 .

# 2. 推送到镜像仓库
docker tag ssa-r-statistics:1.0.2 registry.cn-beijing.aliyuncs.com/aiclinical/ssa-r-statistics:1.0.2
docker push registry.cn-beijing.aliyuncs.com/aiclinical/ssa-r-statistics:1.0.2

# 3. 更新 SAE 部署

8. 常见问题

Q1: 构建时 httpuv 安装失败

错误: fatal error: zlib.h: No such file or directory

解决: 添加 zlib1g-dev 到系统依赖

Q2: 构建时 nloptr 安装失败

错误: CMAKE NOT FOUND

解决: 添加 cmake 到系统依赖

Q3: /tmp 权限问题

错误: cannot open file '/tmp/Rtmpxxx': No such file or directory

解决: 不要在启动命令中清理 /tmp

Q4: DEV_MODE 热重载不生效

原因: 没有挂载 volumes

解决:

volumes:
  - ./tools:/app/tools

Q5: 容器启动后无法访问

检查:

  1. 端口映射是否正确
  2. 健康检查是否通过
  3. 查看容器日志

附录:文件结构

r-statistics-service/
├── Dockerfile              # 生产镜像定义
├── docker-compose.yml      # 开发环境编排
├── renv.lock               # R 包版本锁定(备用)
├── .Rprofile               # R 启动配置(备用)
├── plumber.R               # API 入口
├── utils/
│   ├── data_loader.R       # 数据加载(预签名 URL
│   ├── guardrails.R        # 统计护栏
│   ├── error_codes.R       # 错误映射
│   └── result_formatter.R  # 结果格式化
├── tools/
│   └── t_test_ind.R        # 独立样本 T 检验
├── tests/
│   └── fixtures/
│       └── normal_data.csv # 测试数据
├── metadata/               # 工具元数据(预留)
└── templates/              # 解释模板(预留)

文档结束