背景介绍
“矿工”被设计成一款独立的数据抓取工具,核心解决从多个超市抓取商品、供应商、价格、销售流水、采购数据等;
由于不同超市的erp系统千差万别,使用的数据库以及版本存在差异,因此设计上需要满足如下条件:
- 全程无需超市参与(首次实施除外)
- 定时增量同步(间隔在5分钟级上下)
- 数据不允许丢失,允许偶尔的数据重复
- 支持远程调整同步的周期 (特殊时间段需要调整)
- 支持远程暂停同步过程
- 支持远程更新同步逻辑(字段、取值条件等)
- 支持远程维护门店数据库连接方式
- 每个门店每日数据量在2W条记录,需要支持100家门店
- 服务端要有完善的同步过程跟踪,方便后期的监控和报警
总体思路
总体设计思路:
- 每个超市安装一个定时任务的执行框架(不包含超市DB连接配置 和 数据抓取逻辑)
- 云端管理每个超市的数据库连接配置、数据抓取逻辑、是否暂停任务
- 客户端每次执行时,先从云端获取数据库配置、任务列表、并逐个执行任务(包含取数据 和 上传数据)
沿用这个思路,可以有2种实现方案
数据库同步方案
在云端数据库中配置超市DB连接、任务列表、每个任务的select sql和上传insert sql
客户端每次执行过程如下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15本地数据库配置 = 从云端数据库查询本地数据库配置;
任务ID列表 = 从云端数据库查询任务ID列表(同步商品、供应商、销售流水等)
for 任务ID in 任务ID列表 {
查询语句 = 从云端数据库查询指定ID的任务select语句;
同步参数语句 = 从云端数据库获取更新同步参数语句;
查询结果列表 = 执行(查询语句);
if 查询结果列表 is empty {
break;
}
for 查询结果 in 查询结果列表 {
上传insert语句 = 构造insert语句(查询结果);
执行(上传insert语句);
}
更新同步参数;
};
优点
- 服务端实现简单,无需任何开发
缺点
- 客户端复杂,需要查询N次云端数据库(获取DB配置、查询语句、上传insert语句,更新参数语句等等)
- 简单的Sql无法满足复制的数据抓取需求
- 超市数量变多时,云端数据库压较大
api接口同步方案
云端提供统一的api接口
- 获取超市数据库配置接口
- 获取超市任务ID列表接口
- 获取超市指定任务(任务包含:任务ID、任务名、查询语句)
- 接收任务执行结果上传(任务结果构造成json格式,通过http的post上传,并更新任务同步参数)
客户端每次执行过程如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14本地数据库配置 = 获取超市数据库配置;
任务ID列表 = 获取超市任务ID列表
for 任务ID in 任务ID列表 {
任务 = 获取超市指定任务(任务包含:任务ID、任务名、查询语句);
查询结果列表 = 执行(任务.get查询语句);
if 查询结果列表 is empty {
break;
}
返回结果json;
for 查询结果 in 查询结果列表 {
返回结果json.append(查询结果);
}
上传查询结果(返回结果json);
};
优点
- 与云端服务器交互少(整页数据一次打包上传)
- 客户端不用关心同步参数
- 数据量大时,可以在服务端实现分库分表等扩展
缺点
- 服务端实现复杂
最终选择方案
总体评估下来,选择方案2;