消息推送服务数据迁移
1.数据迁移的由来
上一版本的消息服务,由于项目排期时间紧迫&历史模块代码遗留问题,v1版本的消息服务接口直接在内部服务
A
中添加设计(此坑很大,后来慢慢填了),并且获取用户消息列表等信息也是用的userId
直接获取;
v2版本的消息服务接口,由于消息关系数据库做了分表处理,需要根据之前分享数据库分表实现之天衣无缝的分表策略做数据迁移;
v1版本消息列表接口、未读数、消息已读接口需要正常对外提供;
2. 现有的迁移问题
- 消息已读接口在v1中直接使用消息关系表的
id
(单张表)更新操作的,升级到v2
后,此路不通了,为啥? - 因为v2版本的消息做了分表处理,分表参数是
userId
,移动端必须要传给新接口参数userId
,(为啥是新接口,老接口不是还保留的吗?因为v1通过feign调用的v2,所以UserId是必须的你明白了吧~~),feign在spring boot中的使用以后会介绍! - 然而,恰恰,but
-
v1
版本的消息已读接口,直接使用的noticeId
(int 类型的) - 完全
- 不需要,传递 userId
- 怎么办 ???
- 那就,修改消息列表接口,并想办法把
userId
返回给移动端,然后移动端在使用noticeId
调用v1接口传递给v2的时候,想办法从v2中获取出来,使用userId 定位到分表,作更新操作!
3. 如何解决现有问题
- 思索良久,灵光一现,我把之前返回给移动端的消息列表中的
noticeId
给改装了; - 如何改装能把
userId
和noticeId
作为之前的noticeId
给移动端,并且不保证溢出?
3.1 方案1,使用特殊字符隔开并保证是(number类型)
中间使用特殊字母如
00
分隔userId
和noticeId
后来发现和麻烦,因为本身userId
也会有0
结尾的数字,此方案实验几次,没有找到合适的数字
遂放弃!
3.2 方案2,把现有的10进制数转化为8进制,中间放一个9隔开
Beautiful
完美解决
放一下当时实现组合id以及从组合id中拆分userId
和noticeId
的代码
- 组合id
private static final String NOTICE_PANDORA_SEPARATOR = "9";
/**
* userId + 00 + noticeId装成复合id
*/
public static long buildComplexNoticeId(long userId, long noticeId){
String complexId = Joiner.on(NOTICE_PANDORA_SEPARATOR).join(Long.toOctalString(userId), Long.toOctalString(noticeId));
log.debug("complexId:{}", complexId);
return Long.valueOf(complexId);
}
- 拆分
private static final String NOTICE_PANDORA_SEPARATOR = "9";
/**
* noticeId 转 userId 和 noticeId array
* @param noticeId
* @return
*/
public static long[] obtainSplitArray(long noticeId){
log.debug("noticeId:{}", noticeId);
String noticeIdStr = String.valueOf(noticeId);
if(!noticeIdStr.contains(NOTICE_PANDORA_SEPARATOR)){
throw new BizException(NoticePushErrors.REMOVE_CALL_PARAM_ERROR);
}
String[] noticeArray = noticeIdStr.split(NOTICE_PANDORA_SEPARATOR);
long[] noticeLongArray = new long[2];
long usrId10 = Long.valueOf(noticeArray[0], 8);
long noticeId10 = Long.valueOf(noticeArray[1], 8);
noticeLongArray[0] = usrId10;
noticeLongArray[1] = noticeId10;
return noticeLongArray;
}
4. 反思总结
融汇贯通啊~~