Files
FunctionalScaffold/CLAUDE.md
Roog (顾新培) d211074576 main:更新阿里云函数计算配置为 FC 3.0
变更内容:
- 重构函数计算配置文件,移除旧版 aliyun-fc.yaml,新增符合 FC 3.0 标准的 s.yaml。
- 引入 Serverless Devs 工具支持,添加部署、验证、日志查看等命令指引。
- 调整 API 和 Worker 函数配置,支持更灵活的资源分配及自动化管理。
- 更新文档,提供 FC 3.0 部署指南及优化建议。
2026-02-04 10:27:01 +08:00

643 lines
17 KiB
Markdown
Raw Permalink 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.

# CLAUDE.md
本文件为 Claude Code (claude.ai/code) 在此代码仓库中工作时提供指导。
为了方便团队交流,项目的自然语言使用中文,包括代码注释和文档等
## 项目概述
**FunctionalScaffold函数式脚手架** 是一个算法工程化 Serverless 解决方案的脚手架生成器。
### 核心目标
解决三大痛点:
1. **不确定的算力需求** - 需要动态扩缩容能力
2. **算法同学工程化能力不足** - 降低工程化门槛
3. **后端同学集成难度过高** - 标准化接口规范
## 技术架构
采用 **Docker 封装的 Serverless API 服务**方案:
- 算法代码 + 运行环境打包为 Docker 镜像
- 部署到云厂商 Serverless 平台实现自动扩缩容
- FastAPI 作为 HTTP 接口层
- 算法逻辑保持独立和专注
### 架构流程
```
用户请求 → API网关 → 容器实例(冷/热启动)→ FastAPI → 算法程序 → 返回结果
外部服务OSS/数据库)
```
### 代码架构
项目采用 **src layout** 结构Python 最佳实践):
```
src/functional_scaffold/
├── algorithms/ # 算法层 - 所有算法必须继承 BaseAlgorithm
│ ├── base.py # 提供 execute() 包装器(埋点、错误处理)
│ └── prime_checker.py # 示例:质数判断算法
├── api/ # API 层 - FastAPI 路由和模型
│ ├── models.py # Pydantic 数据模型(使用 ConfigDict
│ ├── routes.py # 路由定义(/invoke, /healthz, /readyz, /jobs
│ └── dependencies.py # 依赖注入request_id 生成)
├── core/ # 核心功能 - 横切关注点
│ ├── errors.py # 异常类层次结构
│ ├── logging.py # 结构化日志JSON 格式)
│ ├── metrics.py # Prometheus 指标和装饰器
│ └── tracing.py # 分布式追踪ContextVar
├── utils/ # 工具函数
│ └── validators.py # 输入验证
├── config.py # 配置管理pydantic-settings
└── main.py # FastAPI 应用入口
```
**关键设计模式:**
1. **算法抽象层**:所有算法继承 `BaseAlgorithm`,只需实现 `process()` 方法。`execute()` 方法自动处理埋点、日志和错误包装。
2. **依赖注入**:使用 FastAPI 的 `Depends()` 机制注入 request_id通过 `ContextVar` 在异步上下文中传递。
3. **配置管理**:使用 `pydantic-settings` 从环境变量或 `.env` 文件加载配置,支持类型验证。
4. **可观测性**
- 日志:结构化 JSON 日志pythonjsonlogger自动包含 request_id
- 指标Prometheus 格式request_counter, request_latency, algorithm_counter
- 追踪request_id 关联所有日志和指标
- 日志收集Loki + Promtail 自动收集和查询日志
## 开发命令
### 环境设置
```bash
# 创建虚拟环境并安装依赖(开发模式)
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -e ".[dev]"
```
### 运行服务
```bash
# 方式1使用辅助脚本推荐
./scripts/run_dev.sh
# 方式2直接运行开发模式自动重载
uvicorn functional_scaffold.main:app --reload --port 8000
# 方式3生产模式
uvicorn functional_scaffold.main:app --host 0.0.0.0 --port 8000 --workers 4
```
访问地址:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
- Metrics: http://localhost:8000/metrics
### 测试
```bash
# 运行所有测试
pytest tests/ -v
# 运行单个测试文件
pytest tests/test_algorithms.py -v
# 运行单个测试类
pytest tests/test_algorithms.py::TestPrimeChecker -v
# 运行单个测试方法
pytest tests/test_algorithms.py::TestPrimeChecker::test_prime_numbers -v
# 生成覆盖率报告
pytest tests/ --cov=src/functional_scaffold --cov-report=html
# 查看报告open htmlcov/index.html
# 使用辅助脚本(包含代码检查)
./scripts/run_tests.sh
```
### 代码质量
```bash
# 代码格式化(自动修复)
black src/ tests/
# 代码检查(不修改文件)
black --check src/ tests/
# 代码检查
ruff check src/ tests/
# 自动修复可修复的问题
ruff check --fix src/ tests/
```
配置说明:
- Black: 行长度 100目标 Python 3.9+
- Ruff: 行长度 100目标 Python 3.9+
### Docker
```bash
# 构建镜像
docker build -f deployment/Dockerfile -t functional-scaffold:latest .
# 运行容器
docker run -p 8000:8000 functional-scaffold:latest
# 使用 docker-compose包含 Prometheus + Grafana + Loki
cd deployment
docker-compose up
# Grafana: http://localhost:3000 (admin/admin)
# Prometheus: http://localhost:9090
# Loki: http://localhost:3100
```
### 文档
```bash
# 导出 OpenAPI 规范到 docs/swagger/openapi.json
python scripts/export_openapi.py
```
## 添加新算法
### 1. 创建算法类(继承 BaseAlgorithm
```python
# src/functional_scaffold/algorithms/my_algorithm.py
from typing import Dict, Any
from .base import BaseAlgorithm
class MyAlgorithm(BaseAlgorithm):
"""我的算法类"""
def process(self, input_data: Any) -> Dict[str, Any]:
"""
算法处理逻辑
Args:
input_data: 输入数据
Returns:
Dict[str, Any]: 处理结果
"""
# 实现算法逻辑
result = do_something(input_data)
return {"result": result}
```
### 2. 注册到 `__init__.py`
```python
# src/functional_scaffold/algorithms/__init__.py
from .my_algorithm import MyAlgorithm
__all__ = [..., "MyAlgorithm"]
```
### 3. 添加 API 端点(在 `api/routes.py`
```python
@router.post("/my-endpoint")
async def my_endpoint(
request: MyRequest,
request_id: str = Depends(get_request_id)
):
"""我的算法端点"""
algorithm = MyAlgorithm()
result = algorithm.execute(request.data)
return MyResponse(request_id=request_id, **result)
```
### 4. 定义数据模型(在 `api/models.py`
```python
class MyRequest(BaseModel):
"""我的请求模型"""
model_config = ConfigDict(
json_schema_extra={
"example": {"data": "示例数据"}
}
)
data: str = Field(..., description="输入数据")
```
### 5. 编写测试
```python
# tests/test_my_algorithm.py
def test_my_algorithm():
"""测试我的算法"""
algo = MyAlgorithm()
result = algo.process("测试数据")
assert result["result"] == expected
```
## 配置管理
配置通过 `src/functional_scaffold/config.py``Settings` 类管理:
- 从环境变量读取(不区分大小写)
- 支持 `.env` 文件
- 使用 `pydantic-settings` 进行类型验证
配置示例:
```bash
# .env 文件
APP_ENV=production
LOG_LEVEL=INFO
METRICS_ENABLED=true
```
访问配置:
```python
from functional_scaffold.config import settings
print(settings.app_env) # "production"
```
## 可观测性
### 日志
使用 `core/logging.py``setup_logging()`
```python
from functional_scaffold.core.logging import setup_logging
# 设置日志
logger = setup_logging(level="INFO", format_type="json")
# 记录日志(自动包含 request_id
logger.info("处理请求", extra={"user_id": "123"})
```
**日志特性:**
- 结构化 JSON 格式
- 自动包含 request_id从 ContextVar 中提取)
- 支持文件日志(可选,通过环境变量启用)
- 日志轮转100MB保留 5 个备份)
### 日志收集Loki
项目集成了 Grafana Loki 日志收集系统,支持两种收集模式:
**模式 1: Docker stdio 收集(默认,推荐)**
- 自动收集容器标准输出/错误
- 无需修改应用代码
- 性能影响极小
**模式 2: 文件收集(备用)**
- 日志持久化到文件
- 支持日志轮转
- 需要设置 `LOG_FILE_ENABLED=true`
**查询日志:**
```bash
# 使用 Loki API
curl -G -s "http://localhost:3100/loki/api/v1/query_range" \
--data-urlencode 'query={job="functional-scaffold-app"}'
# 按 request_id 过滤
curl -G -s "http://localhost:3100/loki/api/v1/query_range" \
--data-urlencode 'query={job="functional-scaffold-app"} |= "request-id-here"'
```
**Grafana 仪表板:**
- 访问 http://localhost:3000
- 进入 "日志监控" 仪表板
- 使用 Request ID 输入框过滤特定请求的日志
**相关文档:**
- 完整文档:`docs/loki-integration.md`
- 使用说明:`docs/grafana-dashboard-usage.md`
- 快速参考:`docs/loki-quick-reference.md`
### 指标
使用 `core/metrics.py` 的装饰器:
```python
from functional_scaffold.core.metrics import track_algorithm_execution
@track_algorithm_execution("my_algorithm")
def my_function():
"""我的函数"""
pass
```
可用指标:
- `http_requests_total{method, endpoint, status}` - HTTP 请求总数
- `http_request_duration_seconds{method, endpoint}` - HTTP 请求延迟
- `algorithm_executions_total{algorithm, status}` - 算法执行总数
- `algorithm_execution_duration_seconds{algorithm}` - 算法执行延迟
### 追踪
Request ID 自动注入到所有请求和日志:
```python
from functional_scaffold.core.tracing import get_request_id
# 在请求上下文中获取 request_id
request_id = get_request_id()
```
**Request ID 特性:**
- 自动生成或从请求头 `X-Request-ID` 获取
- 通过 ContextVar 在异步上下文中传递
- 自动添加到所有日志记录中
- 可用于追踪单个请求的完整生命周期
- 在 Grafana 仪表板中可按 request_id 过滤日志
## 部署
### Kubernetes
```bash
kubectl apply -f deployment/kubernetes/deployment.yaml
kubectl apply -f deployment/kubernetes/service.yaml
```
配置说明:
- 3 个副本
- 资源限制256Mi-512Mi 内存250m-500m CPU
- 健康检查:存活探针 (/healthz),就绪探针 (/readyz)
### 阿里云函数计算FC 3.0
```bash
# 安装 Serverless Devs如未安装
npm install -g @serverless-devs/s
# 配置阿里云凭证(首次使用)
s config add
# 部署到阿里云函数计算
cd deployment/serverless && s deploy
# 验证配置语法
cd deployment/serverless && s plan
# 查看函数日志
cd deployment/serverless && s logs --tail
```
### AWS Lambda
```bash
sam deploy --template-file deployment/serverless/aws-lambda.yaml
```
## 必须交付的三大组件
### 1. 接入规范
**API 端点标准:**
- `/invoke` - 同步调用接口
- `/jobs` - 异步任务接口(当前返回 501
- `/healthz` - 存活检查
- `/readyz` - 就绪检查
- `/metrics` - Prometheus 指标
**Schema 规范:**
- 请求/响应 SchemaPydantic 验证)
- 错误响应格式(统一的 ErrorResponse
- 元数据和版本信息(每个响应包含 metadata
### 2. Python SDK 运行时
**已实现的能力:**
- ✅ 参数校验Pydantic + utils/validators.py
- ✅ 错误包装和标准化core/errors.py
- ✅ 埋点core/metrics.py - 延迟、失败率)
- ✅ 分布式追踪的关联 IDcore/tracing.py + RequestIdFilter
- ✅ 日志收集和查询Loki + Promtail
- ⏳ Worker 运行时重试、超时、DLQ - 待实现)
### 3. 脚手架生成器
**已包含的模板:**
- ✅ 示例算法函数algorithms/prime_checker.py
- ✅ Dockerfiledeployment/Dockerfile
- ✅ CI/CD 流水线配置(.github/workflows/
- ✅ Serverless 平台部署 YAMLdeployment/serverless/
- ✅ Grafana 仪表板模板monitoring/grafana/dashboards/
- ✅ 告警规则配置monitoring/alerts/rules.yaml
- ✅ Loki 日志收集配置monitoring/loki.yaml, monitoring/promtail.yaml
## 开发理念
**算法同学只需修改核心算法函数。** 所有基础设施、可观测性、部署相关的工作都由脚手架处理。
算法开发者只需:
1. 继承 `BaseAlgorithm`
2. 实现 `process()` 方法
3. 返回字典格式的结果
框架自动提供:
- HTTP 接口封装
- 参数验证
- 错误处理
- 日志记录
- 性能指标
- 健康检查
- 容器化部署
## 注意事项
1. **Pydantic V2**:使用 `ConfigDict` 而非 `class Config`,使用 `model_config` 而非 `Config`
2. **异步上下文**request_id 使用 `ContextVar` 存储,在异步函数中自动传递。
3. **测试隔离**:每个测试使用 `TestClient`,不需要启动真实服务器。
4. **Docker 构建**Dockerfile 使用非 root 用户appuser包含健康检查。
5. **配置优先级**:环境变量 > .env 文件 > 默认值。
6. **Promtail 版本**:使用 Promtail 3.0.0 或更高版本,以支持较新的 Docker API1.44+)。如果遇到 "client version too old" 错误,需要升级 Promtail 版本。
## 日志收集系统Loki
项目集成了 Grafana Loki 日志收集系统,提供强大的日志查询和分析能力。
### 架构
```
应用容器 (stdout/stderr)
Docker Engine
Promtail (日志采集器)
Loki (日志存储)
Grafana (可视化)
```
### 服务组件
**docker-compose 包含以下服务:**
- **app**: 应用服务(端口 8111
- **loki**: 日志存储服务(端口 3100
- **promtail**: 日志采集服务(端口 9080
- **grafana**: 可视化服务(端口 3000
- **prometheus**: 指标收集服务(端口 9090
- **redis**: 缓存服务(端口 6380
### 日志收集模式
#### 模式 1: Docker stdio 收集(默认)
**特点:**
- ✅ 无需修改应用代码
- ✅ 自动收集容器标准输出/错误
- ✅ 性能影响极小
- ✅ 推荐用于生产环境
**配置:**
应用容器需要添加标签(已配置):
```yaml
labels:
logging: "promtail"
logging_jobname: "functional-scaffold-app"
```
#### 模式 2: 文件收集(备用)
**特点:**
- ✅ 日志持久化到文件
- ✅ 支持日志轮转100MB5个备份
- ✅ 适合需要本地日志文件的场景
**启用方式:**
```yaml
# docker-compose.yml
environment:
- LOG_FILE_ENABLED=true
- LOG_FILE_PATH=/var/log/app/app.log
```
### 日志格式
所有日志使用 JSON 格式,自动包含以下字段:
- `asctime`: 时间戳
- `name`: 日志器名称
- `levelname`: 日志级别INFO, WARNING, ERROR
- `message`: 日志消息
- `request_id`: 请求 ID自动添加
- `timestamp`: ISO 格式时间戳
### 查询日志
#### 使用 Loki API
```bash
# 查询所有日志
curl -G -s "http://localhost:3100/loki/api/v1/query_range" \
--data-urlencode 'query={job="functional-scaffold-app"}'
# 按 request_id 过滤
curl -G -s "http://localhost:3100/loki/api/v1/query_range" \
--data-urlencode 'query={job="functional-scaffold-app"} |= "request-id-here"'
# 查询错误日志
curl -G -s "http://localhost:3100/loki/api/v1/query_range" \
--data-urlencode 'query={job="functional-scaffold-app", level="ERROR"}'
```
#### 使用 Grafana 仪表板
1. 访问 http://localhost:3000admin/admin
2. 进入 "日志监控" 仪表板
3. 使用 Request ID 输入框过滤特定请求的日志
**仪表板面板:**
- **日志流(实时)**: 实时日志流
- **日志量趋势**: 按时间和级别统计
- **日志级别分布**: INFO/WARNING/ERROR 分布
- **错误日志**: 只显示 ERROR 级别
#### 使用 Grafana Explore
1. 访问 http://localhost:3000/explore
2. 选择 Loki 数据源
3. 使用 LogQL 查询语言
**常用查询:**
```logql
# 查询所有日志
{job="functional-scaffold-app"}
# 查询错误日志
{job="functional-scaffold-app", level="ERROR"}
# 按 request_id 过滤
{job="functional-scaffold-app"} |= "request-id-here"
# 使用 JSON 解析
{job="functional-scaffold-app"} | json | request_id="request-id-here"
# 统计日志量
sum by (level) (count_over_time({job="functional-scaffold-app"}[5m]))
```
### 验证和测试
```bash
# 验证 Loki 集成
./scripts/verify_loki.sh
# 测试 Request ID 过滤
./scripts/test_request_id_filter.sh
```
### 配置文件
- **Loki 配置**: `monitoring/loki.yaml`
- 日志保留期: 7 天
- 摄入速率限制: 10MB/s
- 自动压缩和清理
- **Promtail 配置**: `monitoring/promtail.yaml`
- Docker stdio 收集配置
- 文件收集配置
- JSON 日志解析规则
- **Grafana Provisioning**: `monitoring/grafana/`
- 数据源自动配置datasources/
- 仪表板自动加载dashboards/
### 故障排查
**看不到日志:**
1. 检查服务状态: `docker-compose ps`
2. 查看 Promtail 日志: `docker-compose logs promtail`
3. 验证容器标签: `docker inspect <container> | grep Labels`
**Docker socket 权限问题:**
```bash
sudo chmod 666 /var/run/docker.sock
```
**日志延迟:**
- Promtail 每 5 秒刷新一次
- 建议等待 5-10 秒后再查询
### 相关文档
- **完整文档**: `docs/loki-integration.md` - 包含查询示例、故障排查、性能优化
- **快速参考**: `docs/loki-quick-reference.md` - 常用命令和 LogQL 查询
- **仪表板使用**: `docs/grafana-dashboard-usage.md` - Grafana 仪表板使用说明
- **实施总结**: `docs/loki-implementation-summary.md` - 架构和实施细节
- **监控目录**: `monitoring/README.md` - 配置文件说明