客户主数据从吉客云同步到下游:一条 QUERY 策略的实战拆解
这个策略解决什么问题
客户主数据从源系统推到下游账套,看起来是最没有技术含量的一类同步——拉一张客户档案表,按编码或时间抽增量,落到目标系统就完事。但只要是真实在客户现场跑过的人都知道:真正出问题的,往往就是这一类。
- 编码在两个系统里含义不一致,3 个月后两边数字对不上;
- 全量一次拉完后,增量起点没记对,丢数据或重数据;
- 客户在源系统改了名称或分类,目标系统这边没及时刷。
我们这次要拆解的策略,目标就是把"查询客户档案"这一件事做扎实:在轻易云数据集成平台上,用 QUERY 模式从源系统分页拉取,按修改时间做增量,落到下游基础资料库。这条策略本身不复杂,但它是后续所有单据同步(订单、入库单、出库单)的依赖项,质量不达标,整条链都会被拖垮。
数据流向与字段映射
整条策略的数据流向是单向的:源系统 → 轻易云中间层 → 目标账套。本质上源端是一个 QUERY 动作(把数据从源系统读出来),目标端是一个轻量的"写入空操作"或写目标表的动作。
下面这张表是关键字段的对照,我们在多个客户现场都是按这个口径做映射,出错概率最低:
| 业务含义 | 源系统字段 | 中间层字段 | 目标账套字段 | 处理要点 |
|---|---|---|---|---|
| 客户编码 | customerCode | customer_code | 客户代码 | 原样透传,作为两边对账的主键 |
| 客户主键 | customerId | customer_id | 客户内码 | 落中间层时建立源主键到目标主键的映射表 |
| 客户名称 | customerName | customer_name | 客户全称 | 注意源系统可能带前后空格,需要 trim |
| 客户类型 | customerType | customer_type | 客户分类 | 编码映射集中管理,不要写在每条策略里 |
| 起始修改时间 | gmtModifiedBegin | last_sync_time | (无) | 用上次同步时间作为本次拉取的左闭右开窗口起点 |
| 结束修改时间 | gmtModifiedEnd | current_time | (无) | 每次调度取当前时间,作为窗口终点 |
这里要特别说一句:编码映射一定要集中管理。我们见过一些团队在每条策略里都写一份"客户类型 1=VIP、2=普通"的映射,3 个月后源系统加了一个新类型,所有策略全错。轻易云提供统一的映射字典,改一处,全链路生效。
在轻易云上如何配置
这条策略在轻易云数据集成平台(Qeasy)里配置,典型分四块:
1. 源端 QUERY 配置
源端是一个标准的 QUERY 接口,使用 POST 方法,分页参数 pageIndex / pageSize 必须传,每页条数按源系统上限设即可(常见 50/100/200)。增量窗口用两个变量:
{{LAST_SYNC_TIME|datetime}}作为gmtModifiedBegin,轻易云会自动取上次成功调度的时间;{{CURRENT_TIME|datetime}}作为gmtModifiedEnd,取本次调度开始时间。
idCheck 建议在 QUERY 阶段保持 false,因为这里是"按时间窗查列表",不是"按主键查单据",做主键校验反而会误判。
2. 中间层字段映射
源端的 customerCode 作为业务主键透传;customerId 作为系统主键落到中间层的 id_mapping 表,后续所有下游策略(订单、库存)都通过这张表找对应关系。
3. 目标端"写入空操作"
这一步是这次配置里最有意思的一个点:目标端被配置成 api=写入空操作,type=WebAPI,effect=EXECUTE。它的作用不是真的去写一个外部接口,而是让轻易云把中间层的数据落库、生成可被下游策略消费的主数据快照。在多个客户现场我们都用这个模式:基础资料同步阶段,先把数据"沉"到轻易云的中间库,下游单据同步阶段再从这里取,而不是每次都去打源系统。
4. 调度计划
源端拉取调度 0 0,12 * * *(每天 0 点和 12 点各一次);目标端落库调度 23 2 * * *(凌晨 2 点 23 分,故意错开 30 分钟,留出拉取和缓冲时间)。两个调度错峰是稳妥做法。
实施步骤
我们建议分三阶段上线,不要一上来就全量 + 高频:
阶段一:全量初始化
- 手动触发一次,把
LAST_SYNC_TIME留空,源端会按 customerCode 升序全量分页拉; - 中间层落库后,人工抽样对账两边客户数量、关键字段;
- 这一阶段不接入目标端写入,只验证"拉得对不对"。
阶段二:增量起点
- 全量对账通过后,把
LAST_SYNC_TIME设为本次全量结束的时间点(注意:取的是"源系统时间",不是"我们的执行时间"); - 切换到正式调度,先按低频跑(比如每天 1 次),观察 3-5 天,确认增量数据没漏没重。
阶段三:调度频率
- 稳定后,根据客户在源系统改档的频率,把调度提到
0 0,12 * * *(每天 2 次)或更高频; - 这一步是增量与全量双轨:高频增量兜日常,每周一次全量校验,发现漂移立刻告警。
踩坑复盘
这一类策略看似简单,翻车点却很多,我们挑 4 个最常见的:
-
增量起点用了本机时间 典型错误:把
LAST_SYNC_TIME设为"昨天 0 点"这种本机时间。一旦源系统时钟和调度机时钟有漂移,要么漏拉(源端修改时间比窗口起点早),要么重拉(落在窗口内但实际没改)。稳妥做法是用源系统返回的gmtModified字段作为下次窗口的起点,轻易云里用{{LAST_SYNC_VALUE}}类变量承接。 -
分页拉漏最后一页 源端分页接口常见坑:pageIndex 从 0 开始、每页 50 条、返回 total 时才算完。代码层面没处理好"最后一页不满 50 条"的情况,就会漏数据。我们一般让轻易云的分页器在
response.total拉满后自动停。 -
编码映射写在每条策略里 上面已经强调过:集中管理。每个客户在源系统的客户类型枚举都不一样,有些甚至有几十种,绝不能散在策略里。
-
目标端 idCheck 没关 这次目标端是"写入空操作",
idCheck要设成true没问题;但很多团队在源端 QUERY 时也开了 idCheck,导致按时间窗拉数据时,主键匹配不上,轻易云把数据全丢了。这里要分清:QUERY 阶段 idCheck=false,EXECUTE 阶段 idCheck=true。
适用场景与不适用场景
适用:源系统有标准的客户档案分页查询接口、目标系统对客户主数据有持久化要求、后续有单据类同步(订单、库存)依赖本策略落库的主数据。
不适用:源系统不支持按修改时间增量(只能全量)、客户数据量级极小(几千以内,直接手工导入更省事)、目标系统要求实时下发但源系统没有变更通知机制。