【性能优化上】第三方组织结构同步优化一,分状态,分步骤的设计,你 get 到了吗?

在工作中,云产品之间自然少不了各种系统的对接,系统对接自然会涉及到各种鉴权,以及需要将对方系统的组织结构同步到己方内部系统中来

当然,有的产品可能会去对接实际的第三方认证源和同步源,但是成本相对比较高,因为对接一个不同的源就需要去实现一套接口和逻辑,虽然流程大同小异,可实际工作量可不小

因此,大多数产品为了方便和节省人力,是会选择对接 IDaaS,让 IDaaS 去对接各种第三方认证源和同步源

此处的 IDaaS 解释一下:

IDaaS 即 Identity as a Service,直译为身份即服务,是一个构建在云上的身份服务

接下来是关于上篇文章谈到的组织结构同步优化的思考,希望能够给 xdm 带来不一样的思考

  • 坑爹,线上同步近 3w 个用户导致链路阻塞引入发的线上问题,你经历过吗?

基本介绍同步流程

之前是自身的系统去和企微,钉钉这样的第三方认证源/同步源进行对接,耗时耗力

现在是将这些工作全部由一个叫做 IDaaS 的模块来完成,可以说他也是一个第三方系统,只是集成了常用的一些第三方平台的认证源和同步源,专门的人做专门的事效率是最高的

基本交互如下:

【性能优化上】第三方组织结构同步优化一,分状态,分步骤的设计,你 get 到了吗?_第1张图片

过去做的很 low 的同步做法

一个消息近 3 w 用户,数据量 6 M 左右

今天主要是分享关于同步的做法,看了上一篇文章,有一点任何和经验的 xdm 就知道,一个消息里面放近 3w 个用户,这种方式处理真的是简直了,不靠谱,风险非常高,对性能也影响很大

【性能优化上】第三方组织结构同步优化一,分状态,分步骤的设计,你 get 到了吗?_第2张图片

平时数据量小的时候没啥感觉,起量了,灾难就来了,因此我们做需求做功能,要考虑在前面,预防这样灾难性的问题以及对真的出现这种问题的时候,要有预案

【性能优化上】第三方组织结构同步优化一,分状态,分步骤的设计,你 get 到了吗?_第3张图片

第三方组织结构同步性能优化需要思考哪些点

那么经历了上次事故,自然下来要认真思考如何处理这种组织结构同步的问题,并且支持的用户量要30 W 起步(此处指的是 一个租户可以承载 30W,而不是整个平台 30W)

那么我们需要考虑如下几个问题:

  • 从 IDaaS 获取数据的顺序,方式如何处理?
  • 服务 A 与 服务 B 的通信方式,提供多少个 RPC 接口来完成一次顺利的组织结构同步?
  • 在同步数据过程中出现了问题,异常中断了我们需要如何恢复之前已经同步了的数据需要如何去处理
  • 如何才能达到同步 30 w 用户无异常,且能顺利同步成功
  • 同步的数据如果不符合平台的规则,需要筛选出来,并注明冲突原因,返回给前端页面

【性能优化上】第三方组织结构同步优化一,分状态,分步骤的设计,你 get 到了吗?_第4张图片

其实将上述问题思考清楚,完整的回答完毕,基本上这个优化方案就可以落地了,那么我们开始吧

从 IDaaS 获取数据的顺序,方式如何处理?

服务 A 去找 IDaaS 进行数据同步的时候,我们可以分成四个阶段

【性能优化上】第三方组织结构同步优化一,分状态,分步骤的设计,你 get 到了吗?_第5张图片

  • 第一阶段,创建任务,保证同一个时间同一个租户只有一个同步任务在执行
  • 第二个阶段,从 IDaaS 处分页获取组再分批次给到 服务 B

在这个阶段的时候,可能会考虑到一次性将组获取过来不就好了吗?一个租户下面也不会有多少用户组吧?

实际上大一点的客户,光组的数据就有 2-3 w 个,甚至很多的,因此还是需要分页去获取,然后分批次推送给服务 B,服务 B 将数据给到临时用户组表中

  • 第三个阶段 ,从 IDaaS 处分页获取用户,并批次给到服务 B,服务 B 将数据给到临时用户表中
  • 第四个阶段,触发并通知可以正式将数据写入到正式表

服务 A 与 服务 B 的通信方式,提供多少个 RPC 接口来完成一次顺利的组织结构同步?

目前来服务 A 作为调用者,那么服务 B 自然是提供 4 个接口,分别为

【性能优化上】第三方组织结构同步优化一,分状态,分步骤的设计,你 get 到了吗?_第6张图片

  • 创建同步任务
  • 同步组
  • 同步用户
  • 写入正式表

在同步数据过程中出现了问题,异常中断了我们需要如何恢复,之前已经同步了的数据需要如何去处理?

那这个时候,对于组织结构同步的话我们需要这样来设计,首先会考虑我们本次的数据同步是属于全量同步,还是属于增量同步

例如,我们同步过用户数据,则在我们自己的平台上会有一个 /IDaaS 的组,同步之前校验平台中是否有这个组,若有,则为增量同步,反之,则是全量同步

对于增加每一个阶段的可靠性,以及程序的健壮性,并且受到异常中断之后,还能够进行断点续传,我们针对每一个阶段设计了这样的流程:

总体说明

总体来说,我们设计 3 张表4 个同步状态,以及 14 个同步步骤

【性能优化上】第三方组织结构同步优化一,分状态,分步骤的设计,你 get 到了吗?_第7张图片

3 张表

其中包含一张同步记录表,一张临时用户表,一张临时用户组表

同步记录表存放这些关键字段

  • 基本的租户 id
  • 记录重试次数
  • 同步类型
  • 当前的同步状态
  • 当前的同步步骤

临时用户组表存放这些 关键字段

  • 基本的租户 id
  • 组 id
  • 组名
  • 父组 id
  • 是否合法
  • 非法原因

临时用户表中存放这些关键字段

  • 基本的租户 id
  • 用户 id
  • 用户名
  • 组 id
  • 是否合法
  • 非法原因

可以看出,3 张表主要都是通过租户 id 来进行匹配的

4 个同步状态

- sync_in 同步中
- sync_interrupt 同步中断
- sync_fail 同步失败
- sync_success 同步成功

14 个同步步骤(全量+增量)

同步临时数据步骤

1 sync_begin 同步开始
2 sync_temp_group 同步组信息到临时组
3 sync_temp_user 同步用户到临时表

全量步骤

4 full_sync_group 全量同步临时表中的组到正式表
5 full_sync_user 全量同步临时表中的用户到正式表

增量步骤

6 incr_sync_markup_group 标记组步骤
7 incr_sync_markup_user 标记用户步骤
8 incr_sync_delete_user 从正式表中删除用户步骤
9 incr_sync_add_group 将临时表中的组写入到正式表中
10 incr_sync_move_user 处理正式表中移动用户
11 incr_sync_add_user 将临时表中的用户添加到正式表中
12 incr_sync_edit_user 编辑正式表中的用户
13 incr_sync_delete_group 删除正式表中的组
14 sync_end 增量同步结束

接下来我们可以按照上述提供的四个接口来进行阐述上述同步状态和同步步骤都是如何使用的,本次先写前 3 个接口,结果是将第三方的数据全部同步到 服务 B 得了临时表中,且标记好数据是否合法,也是为下一篇留下一个伏笔

创建同步任务

本接口旨在控制一个租户同一时间只能有一个同步任务

  • 校验请求是否有同步记录,如果有,则校验同步状态同步中(sync_in) 或者是 同步中断(sync_interrupt) ,则本次不进行同步
  • 校验平台中是否有 /IDaaS 组,若有则记录同步类型为全量同步(full) ,若没有则记录同步类型为 增量同步(incr)
  • 将同步记录写入到同步记录表中,同步状态为 同步中(sync_in) ,同步步骤为同步开始(sync_begin)

    • 【性能优化上】第三方组织结构同步优化一,分状态,分步骤的设计,你 get 到了吗?_第8张图片

原因如下

此处校验同步状态同步中(sync_in) 或者是 同步中断(sync_interrupt) ,则本次不进行同步,原因如下:

  1. 若触发当前接口,发现租户同步记录中同步状态为 sync_in ,则说明已经有任务在处理同步任务了,无需再次执行
  1. 同步状态为 sync_interrupt,说明这条同步记录之前异常中断,那么本次任务也无需再次执行,另外一边会有一个定时任务去扫同步记录表中的 sync_interrupt 同步状态的数据,轮训去读取后,进行组织结构同步

同步组数据到临时表

本接口旨在将第三方用户组数据全部同步到临时用户组表中,并标记合法与非法数据

【性能优化上】第三方组织结构同步优化一,分状态,分步骤的设计,你 get 到了吗?_第9张图片

  1. 校验当前同步记录的状态是 sync_in,否则不进行处理
  1. 开启事务

    1. 校验当前数据若是第一页数据,若是,则清空临时用户组表,且在同步记录表中记录同步步骤为 sync_temp_group

    2. 若不是第一页数据,则校验同步记录表中的同步步骤是否是 sync_temp_group

      1. 若是,则继续,将第三方的数据逐页进行基本校验后,将数据逐页写入到临时用户组表中,且标记每一条数据合法和非法
      2. 若不是,则返回错误信息,让调用者结束整个流程,此处的调用者即 服务 A

同步用户数据到临时表

本接口旨在将第三方用户数据全部同步到临时用户表中,并标记合法与非法数据

【性能优化上】第三方组织结构同步优化一,分状态,分步骤的设计,你 get 到了吗?_第10张图片

  1. 校验当前同步记录的状态是 sync_in,否则不进行处理
  1. 开启事务

    1. 校验当前数据若是第一页数据,若是,则清空临时用户表,且在同步记录表中记录同步步骤为 sync_temp_user

    2. 若不是第一页数据,则校验同步记录表中的同步步骤是否是 sync_temp_user

      1. 若是,则继续,将第三方的数据逐页进行基本校验后,将数据逐页写入到临时用户表中,且标记每一条数据合法和非法
      2. 若不是,则返回错误信息,让调用者结束整个流程,此处的调用者即 服务 A

总结

通过上述 3 个接口,配合使用上述说到的同步状态和同步步骤,目前为止,就可以将第三方组织结构的所有数据快速高效的放到 服务 B 的临时表中

对于这些临时数据,如果出现了异常中断,那么若再次触发同步任务,我们清空临时数据,写入本次第三方组织结构数据即可

那么对于如何将临时表数据,写入到正式表中,才是真正的大头

不过也不复杂,对于写入数据到正式表的时候,分成全量同步和增量同步来进行处理,并按照每一个步骤进行校验和处理,就可以达到断点续传的效果,且效率比之前的方案快了不止一点点,详情可以查看下一篇文章

感谢阅读,欢迎交流,点个赞,关注一波 再走吧

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~

关于线上问题的情况,可以查看如下文章:

  • 坑爹,线上同步近 3w 个用户导致链路阻塞引入发的线上问题,你经历过吗?
  • 【性能优化下】组织结构同步优化二,全量同步/增量同步,断点续传

关于认证的相关内容可以查看文章:

  • OAUTH之钉钉第三方授权
  • JWT身份认证(附带源码讲解)

可以进入地址进行体验和学习:https://xxetb.xet.tech/s/3lucCI

你可能感兴趣的:(redis,分布式,数据库,golang,单元测试)