Files
data-engine/docs/USAGE.md
2026-05-29 18:39:32 +08:00

12 KiB
Raw Blame History

Data Engine 通用数据同步引擎 - 使用文档

一、概述

本系统是一个配置驱动的通用数据同步引擎,核心思想是:平台管理 + 接口管理

您只需要通过 API 维护好平台和接口的配置信息(认证方式、请求参数、响应解析、目标表结构),系统就会自动:

  1. 创建目标表(根据 table_definition 自动建表)
  2. 拉取数据(分页请求、多步骤请求、并发处理)
  3. 写入数据库(批量 upsert
  4. 增量同步(通过 filtering 按最后修改时间过滤)
  5. 自动调度(按配置的时间间隔循环执行)
  6. 补偿重试(失败的同步任务自动重试,退避递增)

不需要为每个平台写一行业务代码。


二、数据库初始化

2.1 核心表

首次使用需执行 sql/init_core_tables.sql,创建以下 4 张表:

表名 说明
api_datasource_platform 数据源平台配置(认证信息、限流等)
api_interface 接口配置URL、请求参数、表结构等
sync_task_log 同步任务日志(记录状态,用于补偿)
sync_tracker 同步跟踪(记录每个接口的最后同步时间)

2.2 初始化数据

执行 sql/seed_data.sql 创建腾讯广告平台+接口配置。如需清空重来:

ALTER SEQUENCE api_datasource_platform_id_seq RESTART WITH 1;
ALTER SEQUENCE api_interface_id_seq RESTART WITH 1;
DELETE FROM api_interface;
DELETE FROM api_datasource_platform;
\i sql/seed_data.sql

三、配置说明

3.1 平台管理 (api_datasource_platform)

字段 说明 示例
platform_code 平台编码(唯一) tencent
platform_name 平台名称 腾讯广告
api_base_url API 基础地址 https://api.e.qq.com/v3.0
auth_type 认证类型 OAUTH2 / TOKEN / API_KEY / BASIC
token access_token xxxxx
client_id / client_secret OAuth2 凭证 xxxxx
auth_config 自定义认证配置(JSONB) 详见 3.1.1

3.1.1 auth_config 字段详解

{
  "token_in_query": true,        // token 放在 URL 查询参数
  "query_key": "access_token",   // 参数名,默认 "access_token"
  "header_name": "Authorization", // token 放请求头时的头名
  "header_format": "Bearer {token}",
  "extra_query_params": {        // 额外查询参数
    "timestamp": "{timestamp}",  // {timestamp} 自动替换为当前时间戳
    "nonce": "{nonce}"           // {nonce} 自动替换为随机字符串
  }
}

3.2 接口管理 (api_interface)

字段 说明 示例
platform_id 所属平台 ID 1
name / code 接口名称 / 唯一编码 图片素材 / image
url 接口地址(相对路径) /images/get
method 请求方法 GET / POST
request_config 请求配置(JSONB) 详见 3.2.1
response_config 响应配置(JSONB) 详见 3.2.2
table_definition 表结构定义(JSONB) 详见 3.3

3.2.1 request_config 字段详解

{
  "parameters_location": "query",      // 参数位置: "query"(URL) / "body"(默认)
  "page": 1,
  "page_size": 100,
  "page_param": "page",                // 分页参数名(自定义)
  "page_size_param": "page_size",
  "time_field": "last_modified_time",  // 增量时间字段
  "fields": ["field1", "field2"],      // 请求字段(如音频的 fields
  "prefetch": { ... }                  // 预取配置(见下文)
}

parameters_location 说明

  • 未设置或 "body" → 参数放在 JSON body 中POST 请求)
  • "query" → 参数放在 URL 查询字符串中GET 请求用)
  • method=GET 时,即使不设置也默认走 query

预取prefetch:某些接口需要"先拿列表→遍历每个元素查数据"(如先拉账户列表,再遍历拉图片)。

"prefetch": {
  "url": "/advertiser/get",           // 预取接口地址
  "method": "GET",
  "response_path": "data.list",       // 从响应中取值路径
  "target_param": "account_id",       // 注入主请求的参数名
  "value_field": "account_id"         // 从预取结果取哪个字段
}

并发处理:有 prefetch 的接口会并发处理每个实体,并发数由 config.ymlsync.concurrency 控制。

增量同步:配置了 time_field 的接口,增量同步时会自动生成 filtering 参数:

{"field": "last_modified_time", "operator": "GREATER_EQUALS", "values": ["<timestamp>"]}

3.2.2 response_config 字段详解

系统默认解析的响应格式:

{ "code": 0, "message": "success", "data": { "list": [...], "page_info": { "total_page": N } } }

可通过 response_config 自定义数据路径:

{ "list_path": "data.list" }

3.3 table_definition 字段详解

{
  "table_name": "tencent_image",
  "columns": [
    { "name": "image_id", "type": "VARCHAR(100)", "comment": "图片ID" },
    { "name": "account_id", "type": "BIGINT", "comment": "账户ID" }
  ],
  "conflict_keys": ["image_id", "account_id"]
}

自动添加的列(无需声明):

列名 类型 说明
id BIGSERIAL PRIMARY KEY 自增主键
tenant_id BIGINT 租户 ID
creator VARCHAR(64) 创建人
created_at TIMESTAMPTZ 创建时间
updater VARCHAR(64) 更新人
updated_at TIMESTAMPTZ 更新时间
deleted_at TIMESTAMPTZ 软删除
raw_data JSONB 原始响应数据

四、API 接口

基础地址:http://localhost:3002

4.1 平台管理

方法 路径 说明
POST /api/datasourcePlatform/createDatasourcePlatform 创建平台
GET /api/datasourcePlatform/listDatasourcePlatforms 列表
GET /api/datasourcePlatform/getDatasourcePlatform 详情
GET /api/datasourcePlatform/getPlatformByCode 按编码查
PUT /api/datasourcePlatform/updateDatasourcePlatform 更新
PUT /api/datasourcePlatform/updateDatasourcePlatformStatus 更新状态
DELETE /api/datasourcePlatform/deleteDatasourcePlatform 删除
GET /api/datasourcePlatform/getPlatformStatistics 统计

4.2 接口管理

方法 路径 说明
POST /api/apiInterface/createApiInterface 创建接口
GET /api/apiInterface/listApiInterfaces 列表
GET /api/apiInterface/getApiInterface 详情
PUT /api/apiInterface/updateApiInterface 更新
PUT /api/apiInterface/updateApiInterfaceStatus 更新状态
DELETE /api/apiInterface/deleteApiInterface 删除

4.3 同步控制

方法 路径 说明
POST /api/sync/ctrl/trigger 触发同步
GET /api/sync/ctrl/config 查询配置

触发同步示例:

curl -X POST http://localhost:3002/api/sync/ctrl/trigger \
  -H 'Content-Type: application/json' \
  -d '{"platformCode":"tencent","interfaceCode":"image","fullSync":true}'

响应:

{
  "success": true,
  "tableName": "tencent_image",
  "totalRows": 1500,
  "insertedRows": 1450,
  "duration": "12.3s"
}

五、配置文件 (config.yml)

sync:
  page_size: 100                  # 每次分页请求条数
  concurrency: 5                  # 并发处理数prefetch 遍历实体时)
  retry_count: 3                  # 最大重试次数
  sync_interval_minutes: 60       # 自动同步间隔(分钟)
  compensation_interval_seconds: 300  # 补偿扫描间隔(秒)
  auto_sync_enabled: true         # 是否启用自动同步

tencent:
  oauth:
    client_id: "1112038234"
    client_secret: "GxyjXFbZAs5dnsNQ"
    access_token: "4bacfc7c9b0a31f70ec0eb4771f8b542"
    refresh_token: "d15b37363a42449026d337708516e95e"

六、自动同步机制

6.1 启动流程

  1. 服务启动 → InitAndStartAutoSync 在 goroutine 中启动调度器
  2. 自动扫描所有 ACTIVE 平台下有 table_definition 的接口
  3. sync_tracker 记录 → 全量拉取;有记录 → 增量拉取

6.2 增量同步原理

  • sync_tracker 表记录每个接口的最后同步时间
  • 配置了 time_field 的接口,增量时生成 filtering=[{"field":"last_modified_time","operator":"GREATER_EQUALS","values":["<时间戳>"]}]
  • 不支持时间过滤的接口(如 audio/advertiser每次全量ON CONFLICT 去重

6.3 异常中断恢复

  • 同步开始前写 sync_tracker.sync_status='running'
  • 同步完成后写 'success'
  • 重启检测到 'running' → 日志告警 → 重新全量

七、补偿机制

7.1 工作原理

  1. 同步失败 → 自动写入 sync_task_logstatus=failed
  2. 补偿调度器(随主服务自动启动)每 N 秒扫描 failed 记录
  3. 对未达最大重试次数的任务,调用 SyncByConfig 重试
  4. 重试间隔按退避策略递增5min → 15min → 30min → 60min → 120min
  5. 达最大次数 → 标记 manual_review,等待人工介入

7.2 配置

sync:
  compensation_interval_seconds: 300   # 扫描间隔
  retry_count: 3                       # 最大重试次数

补偿调度器随主服务自动启动,无需手动运行。


八、当前已配置接口(腾讯广告)

接口编码 名称 方法+路径 类型 增量
account_relation 账户列表 GET /advertiser/get 单接口分页 不支持
image 图片素材 GET /images/get prefetch 遍历账户 last_modified_time
video 视频素材 GET /videos/get prefetch 遍历账户 last_modified_time
audio 音频素材 POST /muse_audios/get 单接口 POST 不支持

三个素材表自动包含 verify_status DEFAULT 'PENDING'verified_atverified_by 校验字段。

图片/视频同步流程

SyncByConfig("tencent", "image")
  ├── ① 预取: 分页拉取 /advertiser/get → 774 个 account_id
  │     数据同时存入 tencent_account_relation 表
  ├── ② 并发遍历账户config.yml concurrency=5
  │     每个 account_id → GET /images/get?account_id=xxx&page=1&page_size=100
  │     自动补充 filtering增量时
  │     结果 upsert 到 tencent_image
  └── ③ 更新 sync_tracker 记录同步时间

音频同步流程

单次 POST /muse_audios/get → 分页拉全量 → upsert 到 tencent_audio

九、快速开始

# 1. 建表
psql -h localhost -U postgres -d data-engine -f sql/init_core_tables.sql

# 2. 初始化数据
psql -h localhost -U postgres -d data-engine -f sql/seed_data.sql

# 3. 启动
go run main.go

启动后自动同步和补偿调度器自动运行。也可手动触发:

# 触发图片全量同步
curl -X POST http://localhost:3002/api/sync/ctrl/trigger \
  -H 'Content-Type: application/json' \
  -d '{"platformCode":"tencent","interfaceCode":"image","fullSync":true}'

十、常见问题

Q: 响应格式不符合 {code: 0, data: {list: [...]}} 怎么办?

修改 dynamic_sync.goparseResp 函数。

Q: 如何添加新平台?

调用平台管理 API 创建平台 → 调用接口管理 API 创建接口(带 table_definition)→ 系统自动建表并同步。

Q: prefetch 的响应格式要求?

必须是 JSONresponse_path 指向一个数组。如 response_path: "data.list"data.list 取值。

Q: 如何排查同步失败?

  1. GET /api/sync/ctrl/config?platformCode=xxx 查看配置
  2. 查询 sync_task_log 表看失败记录
  3. 补偿调度器会自动重试,日志会打印重试过程