2. 环境准备与工具链选型:Python 3.9+、Flask/FastAPI框架、Docker、Redis、MySQL、Prometheus+Grafana监控栈的安装与配置

在开始风控评分模型的Serving部署之前,必须搭建一套稳定、可扩展且可观测的基础设施环境。本章将围绕Python运行时、Web框架、容器化、数据存储与监控告警五个维度,完成工具链的选型论证与安装配置。所有组件均采用当前生产环境的主流版本,确保课程案例可直接迁移至企业级部署场景。

2.1 工具链选型总览

风控评分模型Serving对延迟、并发、数据一致性与可观测性有严格要求。下表对比了各候选组件的核心特性与选型结论:

组件 候选方案 选型结论 核心理由
Python版本 3.8 / 3.9 / 3.10 / 3.11 Python 3.9+ 3.9引入zoneinfo与类型提示增强,兼容主流ML库与异步框架
Web框架 Flask / FastAPI / Django FastAPI + Flask双栈 FastAPI处理高并发推理API,Flask用于管理后台与简单路由
容器化 Docker / Podman / containerd Docker + Docker Compose 生态最成熟,Compose便于多服务编排,适合本地开发与CI/CD
缓存/队列 Redis / Memcached / RabbitMQ Redis 7.x 支持数据结构丰富、持久化、Pub/Sub,适合特征缓存与异步任务
持久化存储 MySQL / PostgreSQL / SQLite MySQL 8.0+ 风控场景广泛使用,事务支持好,与ORM配合成熟
监控栈 Prometheus+Grafana / ELK / Zabbix Prometheus + Grafana 云原生标准,指标采集灵活,Grafana可视化丰富
选型提示: 本课程采用FastAPI作为主要推理API框架,同时保留Flask用于管理端。实际生产环境中,若团队对异步编程经验不足,可统一使用Flask+Gunicorn;若追求极致吞吐,推荐FastAPI+Uvicorn。

2.2 整体架构与组件关系

下图展示了风控评分模型Serving的完整工具链架构,各组件之间的数据流与依赖关系一目了然:

风控评分模型Serving工具链架构图 风控评分模型Serving工具链架构 客户端 / 业务系统 FastAPI 推理API (Uvicorn) 端口 8000 | 异步高并发 评分模型引擎 (ONNX / PMML / Sklearn) 模型加载 | 特征工程 | 评分计算 数据存储层 MySQL 8.0 (持久化) Redis 7.x (缓存/队列) MinIO (模型文件) Prometheus + Grafana 监控栈 指标采集 | 告警规则 | 可视化仪表盘 说明:所有组件均运行在Docker容器中,通过docker-compose统一编排;Flask管理后台(端口5000)作为可选组件

2.3 Python 3.9+ 环境安装

推荐使用pyenv管理多版本Python,避免系统环境污染。以下为Ubuntu 22.04环境下的安装步骤:

# 安装pyenv依赖
sudo apt update
sudo apt install -y make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev \
libffi-dev liblzma-dev

# 安装pyenv
curl https://pyenv.run | bash

# 配置环境变量(写入 ~/.bashrc)
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
source ~/.bashrc

# 安装Python 3.9.18
pyenv install 3.9.18
pyenv global 3.9.18

# 验证
python --version
# 输出: Python 3.9.18
版本兼容提醒: 部分老旧风控模型依赖的sklearn、pandas版本可能不支持Python 3.11+。建议生产环境锁定Python 3.9.x或3.10.x,避免因Python版本升级导致模型序列化格式不兼容。

2.4 FastAPI + Flask 双框架安装

本课程采用双框架策略:FastAPI处理核心推理API,Flask用于管理后台与模型热加载。创建项目虚拟环境并安装依赖:

# 创建项目目录
mkdir -p ~/risk_model_serving && cd ~/risk_model_serving

# 创建虚拟环境
python -m venv venv
source venv/bin/activate

# 安装FastAPI栈
pip install fastapi==0.104.1 uvicorn==0.24.0 pydantic==2.5.2

# 安装Flask栈
pip install flask==3.0.0 flask-cors==4.0.0

# 安装通用依赖
pip install numpy==1.24.3 pandas==2.0.3 scikit-learn==1.3.2 \
            joblib==1.3.2 redis==5.0.1 pymysql==1.1.0 \
            sqlalchemy==2.0.23 prometheus-client==0.19.0

# 冻结依赖
pip freeze > requirements.txt

2.5 Docker 与 Docker Compose 安装

所有中间件(Redis、MySQL、Prometheus、Grafana)均通过Docker运行,确保环境一致性。安装命令如下:

# 卸载旧版本
sudo apt remove docker docker-engine docker.io containerd runc

# 安装依赖
sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release

# 添加Docker官方GPG密钥
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 设置仓库
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 安装Docker Engine
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io \
                    docker-compose-plugin

# 将当前用户加入docker组(避免每次sudo)
sudo usermod -aG docker $USER
newgrp docker

# 验证
docker --version
docker compose version

2.6 Redis 7.x 容器部署

Redis用于特征缓存、模型版本元数据存储与异步任务队列。使用Docker Compose统一管理:

# 创建docker-compose.yml(后续会逐步扩展)
cat > docker-compose.yml << 'EOF'
version: '3.8'

services:
  redis:
    image: redis:7.2-alpine
    container_name: risk-redis
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    command: redis-server --appendonly yes --requirepass risk_redis_2024
    restart: unless-stopped

volumes:
  redis_data:
EOF

# 启动Redis
docker compose up -d redis

# 验证连接
docker exec -it risk-redis redis-cli -a risk_redis_2024 ping
# 输出: PONG

2.7 MySQL 8.0 容器部署

MySQL存储评分结果、特征快照、模型元数据与业务配置表。部署配置如下:

# 在docker-compose.yml中追加MySQL服务
cat >> docker-compose.yml << 'EOF'

  mysql:
    image: mysql:8.0.35
    container_name: risk-mysql
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: risk_root_2024
      MYSQL_DATABASE: risk_score
      MYSQL_USER: risk_app
      MYSQL_PASSWORD: risk_app_2024
    volumes:
      - mysql_data:/var/lib/mysql
      - ./init_sql:/docker-entrypoint-initdb.d
    command: --default-authentication-plugin=mysql_native_password
             --character-set-server=utf8mb4
             --collation-server=utf8mb4_unicode_ci
    restart: unless-stopped

volumes:
  redis_data:
  mysql_data:
EOF

# 创建初始化SQL目录
mkdir -p init_sql

# 创建基础表结构
cat > init_sql/01_create_tables.sql << 'SQL'
CREATE TABLE IF NOT EXISTS score_record (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    request_id VARCHAR(64) NOT NULL UNIQUE,
    feature_hash VARCHAR(64),
    score DECIMAL(10,4),
    model_version VARCHAR(32),
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_create_time (create_time),
    INDEX idx_request_id (request_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS model_metadata (
    id INT AUTO_INCREMENT PRIMARY KEY,
    model_name VARCHAR(64) NOT NULL,
    model_version VARCHAR(32) NOT NULL,
    model_path VARCHAR(256),
    status TINYINT DEFAULT 0,
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY uk_model_version (model_name, model_version)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
SQL

# 启动MySQL
docker compose up -d mysql

# 验证连接
docker exec -it risk-mysql mysql -uroot -prisk_root_2024 \
  -e "SELECT VERSION();"
# 输出: 8.0.35

2.8 Prometheus + Grafana 监控栈部署

监控栈是生产环境的必备组件。Prometheus负责指标采集,Grafana提供可视化仪表盘。部署步骤如下:

# 创建Prometheus配置文件目录
mkdir -p prometheus

# 编写Prometheus配置
cat > prometheus/prometheus.yml << 'EOF'
global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'risk-model-api'
    static_configs:
      - targets: ['host.docker.internal:8000']
    metrics_path: '/metrics'

  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']
EOF

# 在docker-compose.yml中追加监控服务
cat >> docker-compose.yml << 'EOF'

  prometheus:
    image: prom/prometheus:v2.48.0
    container_name: risk-prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/usr/share/prometheus/console_libraries'
      - '--web.console.templates=/usr/share/prometheus/consoles'
    restart: unless-stopped

  grafana:
    image: grafana/grafana:10.2.2
    container_name: risk-grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=risk_grafana_2024
      - GF_INSTALL_PLUGINS=grafana-piechart-panel
    volumes:
      - grafana_data:/var/lib/grafana
    restart: unless-stopped

volumes:
  redis_data:
  mysql_data:
  prometheus_data:
  grafana_data:
EOF

# 启动所有服务
docker compose up -d

# 验证所有容器状态
docker compose ps

# 访问Grafana: http://localhost:3000 (admin/risk_grafana_2024)
# 访问Prometheus: http://localhost:9090

2.9 环境验证与健康检查

部署完成后,执行以下脚本验证所有组件是否正常运行:

#!/bin/bash
# health_check.sh - 环境健康检查脚本

echo "===== 风控评分模型Serving环境健康检查 ====="
echo ""

# 1. Python版本
echo "[1] Python版本检查"
python_version=$(python --version 2>&1)
echo "  $python_version"
echo ""

# 2. Docker
echo "[2] Docker状态检查"
docker info >/dev/null 2>&1 && echo "  Docker: 运行中" || echo "  Docker: 未运行"
echo ""

# 3. Redis
echo "[3] Redis连接检查"
redis_ping=$(docker exec risk-redis redis-cli -a risk_redis_2024 ping 2>/dev/null)
echo "  Redis: $redis_ping"
echo ""

# 4. MySQL
echo "[4] MySQL连接检查"
mysql_status=$(docker exec risk-mysql mysqladmin ping -uroot -prisk_root_2024 2>/dev/null)
echo "  MySQL: $mysql_status"
echo ""

# 5. Prometheus
echo "[5] Prometheus状态检查"
prom_status=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:9090/-/healthy 2>/dev/null)
echo "  Prometheus: HTTP $prom_status"
echo ""

# 6. Grafana
echo "[6] Grafana状态检查"
grafana_status=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/api/health 2>/dev/null)
echo "  Grafana: HTTP $grafana_status"
echo ""

echo "===== 检查完成 ====="
生产环境建议:
  • Redis与MySQL的密码应通过环境变量或密钥管理服务(Vault)注入,避免明文写在docker-compose.yml中。
  • Prometheus的scrape_interval可根据模型推理QPS调整,高并发场景建议缩短至5-10秒。
  • Grafana默认使用SQLite存储仪表盘元数据,生产环境建议切换为MySQL或PostgreSQL。

2.10 工具链版本兼容性矩阵

下表汇总了本课程所有组件的推荐版本与兼容性要求,确保后续章节的代码与配置能够无缝衔接:

组件 推荐版本 最低版本 关键依赖 端口
Python 3.9.18 3.8 — —
FastAPI 0.104.1 0.95 uvicorn >=0.20 8000
Flask 3.0.0 2.3 Werkzeug >=2.3 5000
Docker 24.0.7 20.10 Compose plugin —
Redis 7.2-alpine 6.2 — 6379
MySQL 8.0.35 8.0 pymysql / mysqlclient 3306
Prometheus 2.48.0 2.40 prometheus-client 9090
Grafana 10.2.2 9.5 — 3000