问题描述
SSO单点登录系统(记为A系统)管理用户、部门数据,从上游OA系统获取到用户/部门变化时(通过Kafka消息队列),再通过Kafka将用户信息变更的消息发送至下游的B系统。B系统在内部消费消息,做对应的逻辑处理,保证两个系统数据一致。
发现部分消息的数据处理有问题,且不易排查。具体表现为用户的部门信息变更时,B系统的数据处理出错,与A的组织架构出现不一致行为。
原因分析
双方开展需求会议沟通问题成因,B系统对消息处理的日志有多条报错。最终通过数据库Binlog日志的报错发现问题成因。
问题根源是A系统和B系统数据库存储部门负责人的方式不同,A中负责人作为部门表中的一个字段存储,B系统负责人作为一条记录存放于人员-部门关系表,并将负责人的标记字段设置为“是”。
问题场景
1、消息发送顺序(涉及到各层部门)问题导致部分消息处理出错
2、部门更换消息:变更负责人时可能出现问题,负责人变更后,原负责人是否依然是原部门的成员,mq消息中未给出具体字段标明
3、人员信息变更消息:更换人员的部门时可能出现问题。
B系统当前逻辑:
- 旧的主部门id,结合员工id,在员工-部门关系表中查询
- 如果未查询到记录,插入一条新的员工-主部门记录
- 如果查询到记录,更新记录将旧部门id修改为消息中的新部门id。
问题:更新记录时,员工id-新的主部门id作为表的主键,可能表中已经存在对应的记录导致更新失败(因为员工的非主部门中可能有这个部门,他作为负责人在里面,但是在A系统他并不属于那个部门)
解决方案
A系统:
1、本给出mq消息增加一些新的字段名
2、数据对比:
- 所属部门:先调B系统api查询人员的部门数据,主部门路径dept_id_path对比A系统会的人员的部门路径
- 负责部门:暂时不管路径,只对比最下层的部门id
3、部门变更消息:负责人变更时,添加字段----旧负责人是否还在原部门
4、人员信息变更的消息:人员变更时,添加字段----该人员所有负责部门的信息
5、修复数据:依据错误数据量沟通,调用B系统的api修复/直接修改数据
B系统:
1、同步人员和部门信息时的存在性校验去除。同时考虑通过redis/临时表来记录消费失败的部门消息/redis缓存起来
2、人员关系表,部门不存在后,或人离职后,对应的关系应该逻辑删除
3、部门负责人变更问题,根据mq新字段--旧负责人是否依然是原部门成员,来对原记录是否删除进行判断
4、人员信息变更问题,根据mq新字段--变更人员所属的所有部门,防止主键冲突问题,更改对应部门的主部门表示字段