系统设计 - 两个平台数据的同步系统设计和实现

背景: 实现设备信息在两个平台以前的同步。咱们的平台须要保存设备的信息,同时咱们还须要将设备信息同步到第三方平台。第三方平台提供RESTful接口。redis

整个系统的设计以下:数据库

设备操做(添加,删除,修改)分析网络

  1. 设备操做分红两部分:设备信息更新到本地数据库和同步到电信Iot平台
  2. “设备信息更新到本地数据库”实现比较简单,只要更新本地数据库对应记录便可
  3. “同步到电信Iot平台”相对复杂一些,它在设备信息导入到数据库成功后,当即触发同步操做。因为同步操做可能出现失败(或网络异常,第三服务或自身系统bug等),因此还须要定时任务(xxl-job)定时对失败的任务进行同步
  4. 因为可能有多个时机触发同步操做,为了不对同一个设备同时被多个线程执行屡次同步操做而出现数据不一致的问题,因此须要在同步模块中增长同步机制,经过redis的分布式锁保证同一时刻,同一个设备同时只能被一个线程操做

设备状态机设计多线程

这里咱们引入状态机保证设备操做的事物性。设备状态图如上图,详细描述以下:

  1. 新增设备 a. 当新增设备时,添加设备到电信Iot平台,若是执行成功,则状态设置为 “已彻底同步”。若是执行失败,则状态设置为 “同步失败”; b. 对“同步失败”的设备执行从新添加,若是成功则设置 “已彻底同步”,不然状态不变分布式

  2. 当设备彻底同步后,而后设备的信息被修改,再将修改的信息同步到第三方平台 a. 修改设备后,设备的状态修改成 “部分同步” b. 调用设备修改接口同步信息到第三方平台,若是成功,则状态设置为 “已彻底同步”,若是失败,则状态不变优化

这里:第三方的设备同步接口必须保证幂等线程

设备增长操做 设备增长同步的详细步骤设计

详细描述以下:

  1. 判断当前分布式锁是否可用,若是锁不可用,则当即结束,不然下一步(此步保证当有不少线程时同时触发同步操做时,保证只有一个或少许线程进入后面的步骤)
  2. 获取分布式锁,若是获取失败,则等待。若是获取锁成功,则下一步
  3. 获取全部状态为 “未同步” 的设备,调用第三方添加接口执行添加操做,当执行完毕后,会执行以下判断 a. 调用第三方可能会第三方平台限流的缘由失败,此时若是咱们还继续调用接口进行添加是没有意义,则当前线程从新获取锁延长持有锁的时间,并等待Ns直到限流的期限结束,再进行后续操做 b. 判断当前已经持有锁的时间,若是持有锁的时长超过必定的阈值(此时当前线程还在锁的持有时间内),则从新获取锁延长持有锁的时间
  4. 获取全部状态为 “同步失败” 的设备,而后执行和 “未同步”的设备相同的步骤
  5. 最后在finally代码块中释放锁

触发“设备增长同步”的时机:3d

  1. 当新增设备成功
  2. 当批量导入任务当即执行
  3. 定时任务定时触发

设备删除cdn

详细步骤以下:

  1. 获取分布式锁,这里的步骤和“设备同步增长”相似,这里略
  2. 标记能够删除设备
  3. 调用第三方接口进行删除 a. 若是设备的状态为 “未完成”或 “同步失败”(此时设备未同步到第三方平台),则跳过本步骤,只要从本地数据删除便可 b. 若是设备的状态为 “未完成”或 “同步失败”(此时设备未同步到第三方平台),则须要同时从第三方平台删除记录和本地数据删除。若是从第三方删除成功或第三方提示设备不存在,则再从本地删除记录。若是第三方提示删除失败,则当即结束
  4. 从本地删除记录

删除操做有可能在第2,3步失败,因此须要定时任务,扫描已经标记删除的设备,从新执行2,3步。同时这里须要保证第2,3步的幂等操做。因为业务的须要,可能须要在第2,3步前先获取分布式锁。

触发“设备删除同步”的时机:

  1. 当删除设备时成功
  2. 定时任务定时触发

设备修改 设备修改使用相似设备添加方法来实现

  1. 当设备被修改触发设备同步流程
  2. 更新设备的信息,并设置状态为 “未彻底同步”
  3. 将设备信息同步到第三方平台,若是成功,则设置状态为“已彻底同步”,若是失败,则状态不变

定时任务获取设备状态为 “未彻底同步”,并执行上面的第2,3步步骤执行同步操做

这里保证同一个设备只能被一个线程操做,即便咱们使用分布式服务同一设备同时也只能一个服务一个线程操做

此方案后续能够优化之处

  1. 优化分布式锁的粒度,从而提升效率
  2. 获取分布式锁后,经过多线程进行同步从而操做提升同步效率
  3. 第三平台也有可能执行设备的修改和删除操做,此时此平台也须要通知咱们的系统并执行同步操做。咱们平台能够考虑使用MQ解耦。
相关文章
相关标签/搜索