在工作中,雲產品之間自然少不了各種系統的對接,系統對接自然會涉及到各種鑑權,以及需要將對方系統的組織結構同步到己方內部系統中來
當然,有的產品可能會去對接實際的第三方認證源和同步源,但是成本相對比較高,因為對接一個不同的源就需要去實現一套接口和邏輯,雖然流程大同小異,可實際工作量可不小
因此,大多數產品為了方便和節省人力,是會選擇對接 IDaaS,讓 IDaaS 去對接各種第三方認證源和同步源
此處的 IDaaS 解釋一下:
IDaaS 即 Identity as a Service,直譯為身份即服務,是一個構建在雲上的身份服務
接下來是關於上篇文章談到的組織結構同步優化的思考,希望能夠給 xdm 帶來不一樣的思考
- 坑爹,線上同步近 3w 個用户導致鏈路阻塞引入發的線上問題,你經歷過嗎?
基本介紹同步流程
之前是自身的系統去和企微,釘釘這樣的第三方認證源/同步源進行對接,耗時耗力
現在是將這些工作全部由一個叫做 IDaaS 的模塊來完成,可以説他也是一個第三方系統,只是集成了常用的一些第三方平台的認證源和同步源,專門的人做專門的事效率是最高的
基本交互如下:
過去做的很 low 的同步做法
一個消息近 3 w 用户,數據量 6 M 左右
今天主要是分享關於同步的做法,看了上一篇文章,有一點任何和經驗的 xdm 就知道,一個消息裏面放近 3w 個用户,這種方式處理真的是簡直了,不靠譜,風險非常高,對性能也影響很大
平時數據量小的時候沒啥感覺,起量了,災難就來了,因此我們做需求做功能,要考慮在前面,預防這樣災難性的問題以及對真的出現這種問題的時候,要有預案
第三方組織結構同步性能優化需要思考哪些點
那麼經歷了上次事故,自然下來要認真思考如何處理這種組織結構同步的問題,並且支持的用户量要30 W 起步(此處指的是 一個租户可以承載 30W,而不是整個平台 30W)
那麼我們需要考慮如下幾個問題:
- 從 IDaaS 獲取數據的順序,方式如何處理?
<!---->
- 服務 A 與 服務 B 的通信方式,提供多少個 RPC 接口來完成一次順利的組織結構同步?
<!---->
- 在同步數據過程中出現了問題,異常中斷了我們需要如何恢復,之前已經同步了的數據需要如何去處理?
<!---->
- 如何才能達到同步 30 w 用户無異常,且能順利同步成功
<!---->
- 同步的數據如果不符合平台的規則,需要篩選出來,並註明衝突原因,返回給前端頁面
其實將上述問題思考清楚,完整的回答完畢,基本上這個優化方案就可以落地了,那麼我們開始吧
從 IDaaS 獲取數據的順序,方式如何處理?
服務 A 去找 IDaaS 進行數據同步的時候,我們可以分成四個階段
- 第一階段,創建任務,保證同一個時間同一個租户只有一個同步任務在執行
<!---->
- 第二個階段,從 IDaaS 處分頁獲取組,再分批次給到 服務 B
在這個階段的時候,可能會考慮到一次性將組獲取過來不就好了嗎?一個租户下面也不會有多少用户組吧?
實際上大一點的客户,光組的數據就有 2-3 w 個,甚至很多的,因此還是需要分頁去獲取,然後分批次推送給服務 B,服務 B 將數據給到臨時用户組表中
- 第三個階段 ,從 IDaaS 處分頁獲取用户,並批次給到服務 B,服務 B 將數據給到臨時用户表中
<!---->
- 第四個階段,觸發並通知可以正式將數據寫入到正式表
服務 A 與 服務 B 的通信方式,提供多少個 RPC 接口來完成一次順利的組織結構同步?
目前來服務 A 作為調用者,那麼服務 B 自然是提供 4 個接口,分別為
- 創建同步任務
<!---->
- 同步組
<!---->
- 同步用户
<!---->
- 寫入正式表
在同步數據過程中出現了問題,異常中斷了我們需要如何恢復,之前已經同步了的數據需要如何去處理?
那這個時候,對於組織結構同步的話我們需要這樣來設計,首先會考慮我們本次的數據同步是屬於全量同步,還是屬於增量同步
例如,我們同步過用户數據,則在我們自己的平台上會有一個 /IDaaS 的組,同步之前校驗平台中是否有這個組,若有,則為增量同步,反之,則是全量同步
對於增加每一個階段的可靠性,以及程序的健壯性,並且受到異常中斷之後,還能夠進行斷點續傳,我們針對每一個階段設計了這樣的流程:
總體説明
總體來説,我們設計 3 張表,4 個同步狀態,以及 14 個同步步驟
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)
原因如下
此處校驗同步狀態是 同步中(sync_in) 或者是 同步中斷(sync_interrupt) ,則本次不進行同步,原因如下:
- 若觸發當前接口,發現租户同步記錄中同步狀態為 sync_in ,則説明已經有任務在處理同步任務了,無需再次執行
<!---->
- 若 同步狀態為 sync_interrupt,説明這條同步記錄之前異常中斷,那麼本次任務也無需再次執行,另外一邊會有一個定時任務去掃同步記錄表中的 sync_interrupt 同步狀態的數據,輪訓去讀取後,進行組織結構同步
同步組數據到臨時表
本接口旨在將第三方用户組數據全部同步到臨時用户組表中,並標記合法與非法數據
- 校驗當前同步記錄的狀態是 sync_in,否則不進行處理
<!---->
-
開啓事務
- 校驗當前數據若是第一頁數據,若是,則清空臨時用户組表,且在同步記錄表中記錄同步步驟為 sync_temp_group
-
若不是第一頁數據,則校驗同步記錄表中的同步步驟是否是 sync_temp_group
- 若是,則繼續,將第三方的數據逐頁進行基本校驗後,將數據逐頁寫入到臨時用户組表中,且標記每一條數據合法和非法
- 若不是,則返回錯誤信息,讓調用者結束整個流程,此處的調用者即 服務 A
同步用户數據到臨時表
本接口旨在將第三方用户數據全部同步到臨時用户表中,並標記合法與非法數據
- 校驗當前同步記錄的狀態是 sync_in,否則不進行處理
<!---->
-
開啓事務
- 校驗當前數據若是第一頁數據,若是,則清空臨時用户表,且在同步記錄表中記錄同步步驟為 sync_temp_user
-
若不是第一頁數據,則校驗同步記錄表中的同步步驟是否是 sync_temp_user
- 若是,則繼續,將第三方的數據逐頁進行基本校驗後,將數據逐頁寫入到臨時用户表中,且標記每一條數據合法和非法
- 若不是,則返回錯誤信息,讓調用者結束整個流程,此處的調用者即 服務 A
總結
通過上述 3 個接口,配合使用上述説到的同步狀態和同步步驟,目前為止,就可以將第三方組織結構的所有數據快速高效的放到 服務 B 的臨時表中
對於這些臨時數據,如果出現了異常中斷,那麼若再次觸發同步任務,我們清空臨時數據,寫入本次第三方組織結構數據即可
那麼對於如何將臨時表數據,寫入到正式表中,才是真正的大頭
不過也不復雜,對於寫入數據到正式表的時候,分成全量同步和增量同步來進行處理,並按照每一個步驟進行校驗和處理,就可以達到斷點續傳的效果,且效率比之前的方案快了不止一點點,詳情可以查看下一篇文章
感謝閲讀,歡迎交流,點個贊,關注一波 再走吧
歡迎點贊,關注,收藏
朋友們,你的支持和鼓勵,是我堅持分享,提高質量的動力
好了,本次就到這裏
技術是開放的,我們的心態,更應是開放的。擁抱變化,向陽而生,努力向前行。
我是阿兵雲原生,歡迎點贊關注收藏,下次見~
關於線上問題的情況,可以查看如下文章:
- 坑爹,線上同步近 3w 個用户導致鏈路阻塞引入發的線上問題,你經歷過嗎?
- 【性能優化下】組織結構同步優化二,全量同步/增量同步,斷點續傳
關於認證的相關內容可以查看文章:
- OAUTH之釘釘第三方授權
<!---->
- JWT身份認證(附帶源碼講解)