298 lines
9.4 KiB
Markdown
298 lines
9.4 KiB
Markdown
|
|
# 天元API调用记录功能 - 实施总结
|
|||
|
|
|
|||
|
|
## 功能概述
|
|||
|
|
|
|||
|
|
本功能实现了天元API调用的成本记录,包括:
|
|||
|
|
1. 在 `feature` 表添加 `cost_price` 字段,存储每个接口的成本价
|
|||
|
|
2. 创建 `tianyuanapi_call_log` 表,记录每次API调用的详细信息
|
|||
|
|
3. 无论成功失败都记录,但只有成功调用才计算成本
|
|||
|
|
4. 提供统计功能,可查询时间段内的调用次数和总成本
|
|||
|
|
|
|||
|
|
## 已完成的工作
|
|||
|
|
|
|||
|
|
### 1. 数据库层面 ✅
|
|||
|
|
|
|||
|
|
**文件:** `ycc-proxy-server/deploy/sql/tianyuanapi_cost_migration.sql`
|
|||
|
|
|
|||
|
|
**修改内容:**
|
|||
|
|
- 在 `feature` 表添加 `cost_price` 字段(decimal(10, 2),默认0.00)
|
|||
|
|
- 创建 `tianyuanapi_call_log` 表,包含以下字段:
|
|||
|
|
- `feature_id`: 关联feature表
|
|||
|
|
- `api_id`: 天元API标识(如:YYSYBE08)
|
|||
|
|
- `order_id`: 关联订单(可选)
|
|||
|
|
- `query_id`: 关联查询(可选)
|
|||
|
|
- `call_status`: 调用状态(0=失败,1=成功)
|
|||
|
|
- `call_time`: 调用时间
|
|||
|
|
- `response_time`: 响应耗时(毫秒)
|
|||
|
|
- `cost_price`: 本次调用成本(成功时有值,失败为0)
|
|||
|
|
- `error_code`: 错误码(失败时)
|
|||
|
|
- `error_message`: 错误信息(失败时)
|
|||
|
|
- `request_params`: 请求参数(JSON)
|
|||
|
|
- `response_data`: 响应数据(JSON,截取前1000字符)
|
|||
|
|
- `transaction_id`: 天元API流水号
|
|||
|
|
|
|||
|
|
**索引设计:**
|
|||
|
|
- `idx_feature_id`: 按feature_id查询
|
|||
|
|
- `idx_api_id`: 按api_id查询
|
|||
|
|
- `idx_order_id`: 按order_id查询
|
|||
|
|
- `idx_query_id`: 按query_id查询
|
|||
|
|
- `idx_call_status`: 按调用状态查询
|
|||
|
|
- `idx_call_time`: 按调用时间查询
|
|||
|
|
- `idx_feature_time`: 复合索引(feature_id + call_time)
|
|||
|
|
|
|||
|
|
### 2. Service层面 ✅
|
|||
|
|
|
|||
|
|
**文件:** `ycc-proxy-server/app/main/api/internal/service/tianyuanapiCallLogService.go`
|
|||
|
|
|
|||
|
|
**新增方法:**
|
|||
|
|
1. `RecordCall(ctx context.Context, opts CallLogOptions) error`
|
|||
|
|
- 记录API调用
|
|||
|
|
- 自动获取feature的成本价
|
|||
|
|
- 成功时记录成本,失败时成本为0
|
|||
|
|
- 异步记录,不影响主流程
|
|||
|
|
|
|||
|
|
2. `GetStatistics(ctx context.Context, filter StatisticsFilter) (*Statistics, error)`
|
|||
|
|
- 获取统计信息
|
|||
|
|
- 支持按feature_id、api_id、时间范围过滤
|
|||
|
|
- 返回:总调用次数、成功次数、失败次数、总成本
|
|||
|
|
|
|||
|
|
### 3. ApiRequestService修改 ✅
|
|||
|
|
|
|||
|
|
**文件:** `ycc-proxy-server/app/main/api/internal/service/apirequestService.go`
|
|||
|
|
|
|||
|
|
**新增字段:**
|
|||
|
|
- `tianyuanapiCallLogService *TianyuanapiCallLogService`
|
|||
|
|
- `apiFeatureMapCache map[string]string` - apiID到featureID的缓存
|
|||
|
|
- `apiFeatureMapMutex sync.RWMutex` - 缓存读写锁
|
|||
|
|
|
|||
|
|
**新增方法:**
|
|||
|
|
1. `callTianyuanApiWithLog(ctx context.Context, featureID, apiID string, params map[string]interface{}) (*tianyuanapi.Response, error)`
|
|||
|
|
- 调用天元API
|
|||
|
|
- 记录调用开始时间
|
|||
|
|
- 计算响应耗时
|
|||
|
|
- 异步记录调用日志
|
|||
|
|
- 返回响应和错误
|
|||
|
|
|
|||
|
|
2. 在 `ProcessRequests` 方法中构建 `apiID -> featureID` 映射缓存
|
|||
|
|
|
|||
|
|
**修改的方法(示例):**
|
|||
|
|
- `ProcessYYSYBE08Request` - 已修改
|
|||
|
|
- `ProcessFLXG0V4BRequest` - 已修改
|
|||
|
|
|
|||
|
|
**待修改的方法(30个):**
|
|||
|
|
剩余30个方法需要将 `a.callTianyuanApiWithLog(ctx, "", "API名称", ...)`
|
|||
|
|
替换为 `a.callTianyuanApiWithLog(ctx, "", "API名称", ...)`
|
|||
|
|
|
|||
|
|
详细列表见:`批量替换API调用说明.md`
|
|||
|
|
|
|||
|
|
### 4. ServiceContext修改 ✅
|
|||
|
|
|
|||
|
|
**文件:** `ycc-proxy-server/app/main/api/internal/svc/servicecontext.go`
|
|||
|
|
|
|||
|
|
**新增模型:**
|
|||
|
|
```go
|
|||
|
|
TianyuanapiCallLogModel model.TianyuanapiCallLogModel
|
|||
|
|
TianyuanapiCallLogService *service.TianyuanapiCallLogService
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**新增初始化:**
|
|||
|
|
```go
|
|||
|
|
tianyuanapiCallLogModel := model.NewTianyuanapiCallLogModel(db, cacheConf)
|
|||
|
|
tianyuanapiCallLogService := service.NewTianyuanapiCallLogService(tianyuanapiCallLogModel, featureModel)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**修改ApiRequestService初始化:**
|
|||
|
|
```go
|
|||
|
|
apiRequestService := service.NewApiRequestService(
|
|||
|
|
c,
|
|||
|
|
featureModel,
|
|||
|
|
productFeatureModel,
|
|||
|
|
userFeatureWhitelistModel,
|
|||
|
|
tianyuanapi,
|
|||
|
|
tianyuanapiCallLogService, // 新增参数
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5. Model生成脚本 ✅
|
|||
|
|
|
|||
|
|
**文件:** `ycc-proxy-server/deploy/sql/generate_tianyuanapi_models.sh`
|
|||
|
|
|
|||
|
|
**功能:**
|
|||
|
|
- 生成 `feature` 表的Model(已更新,包含cost_price字段)
|
|||
|
|
- 生成 `tianyuanapi_call_log` 表的Model
|
|||
|
|
|
|||
|
|
### 6. 文档 ✅
|
|||
|
|
|
|||
|
|
**已创建的文档:**
|
|||
|
|
1. `天元API调用记录修改说明.md` - 详细的修改步骤和示例
|
|||
|
|
2. `批量替换API调用说明.md` - 批量修改API调用方法的指南
|
|||
|
|
|
|||
|
|
## 待完成的工作
|
|||
|
|
|
|||
|
|
### 1. 执行SQL脚本 ⏳
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 在数据库中执行迁移脚本
|
|||
|
|
mysql -u root -p ycc < ycc-proxy-server/deploy/sql/tianyuanapi_cost_migration.sql
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 生成Model代码 ⏳
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd ycc-proxy-server/deploy/sql
|
|||
|
|
bash generate_tianyuanapi_models.sh
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
这将生成以下文件:
|
|||
|
|
- `app/main/model/featureModel_gen.go` (已更新,包含cost_price字段)
|
|||
|
|
- `app/main/model/featureModel.go` (已更新)
|
|||
|
|
- `app/main/model/tianyuanapiCallLogModel_gen.go` (新建)
|
|||
|
|
- `app/main/model/tianyuanapiCallLogModel.go` (新建)
|
|||
|
|
|
|||
|
|
### 3. 批量修改API调用方法 ⏳
|
|||
|
|
|
|||
|
|
**需要修改30个方法,将:**
|
|||
|
|
```go
|
|||
|
|
resp, err := a.callTianyuanApiWithLog(ctx, "", "API名称", map[string]interface{}{
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**替换为:**
|
|||
|
|
```go
|
|||
|
|
ctx := context.Background()
|
|||
|
|
resp, err := a.callTianyuanApiWithLog(ctx, "", "API名称", map[string]interface{}{
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**参考文档:** `批量替换API调用说明.md`
|
|||
|
|
|
|||
|
|
**建议使用IDE批量替换功能:**
|
|||
|
|
1. 打开 `apirequestService.go`
|
|||
|
|
2. 按 `Ctrl+H` 打开查找替换
|
|||
|
|
3. 查找:`a.callTianyuanApiWithLog(ctx, "", "`
|
|||
|
|
4. 替换:`a.callTianyuanApiWithLog(ctx, "", "`
|
|||
|
|
5. 全部替换
|
|||
|
|
|
|||
|
|
**然后手动在每个方法开头添加:**
|
|||
|
|
```go
|
|||
|
|
ctx := context.Background()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. 编译验证 ⏳
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd ycc-proxy-server
|
|||
|
|
go build ./...
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
检查是否有编译错误。
|
|||
|
|
|
|||
|
|
### 5. 测试验证 ⏳
|
|||
|
|
|
|||
|
|
1. 运行项目
|
|||
|
|
2. 发起几个API请求(成功和失败各几次)
|
|||
|
|
3. 检查 `tianyuanapi_call_log` 表,验证:
|
|||
|
|
- 记录是否正确插入
|
|||
|
|
- 成功调用有正确的成本价
|
|||
|
|
- 失败调用成本为0
|
|||
|
|
- 响应耗时是否记录
|
|||
|
|
- 错误信息是否正确
|
|||
|
|
|
|||
|
|
### 6. 后台配置 ⏳
|
|||
|
|
|
|||
|
|
在后台"功能管理"页面,为每个feature配置成本价:
|
|||
|
|
1. 进入"功能管理"
|
|||
|
|
2. 编辑某个功能
|
|||
|
|
3. 设置"天元API调用成本价"字段
|
|||
|
|
4. 保存
|
|||
|
|
|
|||
|
|
## 统计功能使用示例
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
// 获取某个功能在某个时间段的调用统计
|
|||
|
|
filter := StatisticsFilter{
|
|||
|
|
FeatureID: "feature-id-123",
|
|||
|
|
StartDate: time.Now().AddDate(0, 0, -30), // 30天前
|
|||
|
|
EndDate: time.Now(),
|
|||
|
|
}
|
|||
|
|
stats, err := ctx.TianyuanapiCallLogService.GetStatistics(context.Background(), filter)
|
|||
|
|
if err == nil {
|
|||
|
|
fmt.Printf("总调用次数: %d\n", stats.TotalCalls)
|
|||
|
|
fmt.Printf("成功次数: %d\n", stats.SuccessCalls)
|
|||
|
|
fmt.Printf("失败次数: %d\n", stats.FailedCalls)
|
|||
|
|
fmt.Printf("总成本: %.2f元\n", stats.TotalCost)
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## SQL查询示例
|
|||
|
|
|
|||
|
|
### 查询某个接口的调用记录
|
|||
|
|
```sql
|
|||
|
|
SELECT * FROM tianyuanapi_call_log
|
|||
|
|
WHERE api_id = 'YYSYBE08'
|
|||
|
|
ORDER BY call_time DESC
|
|||
|
|
LIMIT 100;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 统计某天所有接口的调用情况
|
|||
|
|
```sql
|
|||
|
|
SELECT
|
|||
|
|
api_id,
|
|||
|
|
COUNT(*) as total_calls,
|
|||
|
|
SUM(CASE WHEN call_status = 1 THEN 1 ELSE 0 END) as success_calls,
|
|||
|
|
SUM(CASE WHEN call_status = 0 THEN 1 ELSE 0 END) as failed_calls,
|
|||
|
|
SUM(cost_price) as total_cost
|
|||
|
|
FROM tianyuanapi_call_log
|
|||
|
|
WHERE DATE(call_time) = CURDATE()
|
|||
|
|
GROUP BY api_id;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 查询成功率最低的接口
|
|||
|
|
```sql
|
|||
|
|
SELECT
|
|||
|
|
api_id,
|
|||
|
|
COUNT(*) as total_calls,
|
|||
|
|
SUM(CASE WHEN call_status = 1 THEN 1 ELSE 0 END) as success_calls,
|
|||
|
|
(SUM(CASE WHEN call_status = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*)) as success_rate
|
|||
|
|
FROM tianyuanapi_call_log
|
|||
|
|
WHERE call_time >= DATE_SUB(NOW(), INTERVAL 7 DAY)
|
|||
|
|
GROUP BY api_id
|
|||
|
|
ORDER BY success_rate ASC
|
|||
|
|
LIMIT 10;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 注意事项
|
|||
|
|
|
|||
|
|
1. **成本价配置**:需要在后台为每个feature配置成本价,否则所有调用的成本都是0
|
|||
|
|
2. **性能考虑**:调用日志采用异步记录,不影响API响应速度
|
|||
|
|
3. **数据量控制**:response_data只记录前1000字符,避免存储过大
|
|||
|
|
4. **缓存机制**:apiID到featureID的映射在 `ProcessRequests` 时构建,避免频繁查询数据库
|
|||
|
|
5. **失败不收费**:根据需求,调用失败时天元API不收费,所以cost_price为0
|
|||
|
|
|
|||
|
|
## 后续优化建议
|
|||
|
|
|
|||
|
|
1. **定时清理**:可以添加定时任务,定期清理超过一定时间的日志数据(如90天)
|
|||
|
|
2. **成本预警**:可以添加监控,当某个时间段的总成本超过阈值时发送告警
|
|||
|
|
3. **成功率监控**:监控各接口的成功率,低于阈值时告警
|
|||
|
|
4. **性能分析**:分析响应时间,找出性能瓶颈
|
|||
|
|
5. **数据归档**:将历史日志归档到其他存储,避免主表过大
|
|||
|
|
|
|||
|
|
## 文件清单
|
|||
|
|
|
|||
|
|
### 新增文件
|
|||
|
|
1. `deploy/sql/tianyuanapi_cost_migration.sql` - 数据库迁移脚本
|
|||
|
|
2. `deploy/sql/generate_tianyuanapi_models.sh` - Model生成脚本
|
|||
|
|
3. `app/main/api/internal/service/tianyuanapiCallLogService.go` - 调用记录服务
|
|||
|
|
4. `deploy/sql/天元API调用记录修改说明.md` - 详细修改说明
|
|||
|
|
5. `deploy/sql/批量替换API调用说明.md` - 批量替换指南
|
|||
|
|
6. `deploy/sql/天元API调用记录功能完成总结.md` - 本文档
|
|||
|
|
|
|||
|
|
### 修改文件
|
|||
|
|
1. `app/main/api/internal/service/apirequestService.go` - 添加调用记录逻辑
|
|||
|
|
2. `app/main/api/internal/svc/servicecontext.go` - 添加新Model和Service初始化
|
|||
|
|
|
|||
|
|
### 待生成文件(执行脚本后)
|
|||
|
|
1. `app/main/model/featureModel_gen.go` - 已更新
|
|||
|
|
2. `app/main/model/featureModel.go` - 已更新
|
|||
|
|
3. `app/main/model/tianyuanapiCallLogModel_gen.go` - 新建
|
|||
|
|
4. `app/main/model/tianyuanapiCallLogModel.go` - 新建
|
|||
|
|
|