多服务器发布时旧数据适配问题

日期:2019-01-15       浏览:356

一 问题

一个大版本的迭代,保存到Redis中的缓存数据实体类增加了一些属性,就用了一个子类继承旧实体类。获取缓存数据时可以通过Redis的class类型判断是新数据,如果不是,就用旧实体类序列化,代码如下:
  • 旧的实体类
class OldEntity {
    // 旧的属性
    private Integer age; 
}
  • 新的实体类
class NewEntity extends OldEntity {
    // 新增属性
    private String name;
}
  • 从Redis获取数据,适配旧数据
Map<byte[], byte[]> loadedHash = stringRedisTemplate.execute((RedisCallback<Map>) conn -> conn.hGetAll(key.getBytes()));

// private final static ObjectHashMapper SELECTIVE_MAPPER = new ObjectHashMapper();
Object cached = SELECTIVE_MAPPER.fromHash(loadedHash);

if (cached == null)
    return null;

// 判断Redis保存的是不是新的数据模型
if (NewEntity.class.isInstance(cached)) {
    NewEntity result = (NewEntity) cached;
    // TODO 其他业务操作
    
    return result;
}

// 旧的数据模型
OldEntity result = (OldEntity) cached;
// TODO 其他业务操作

return result;
  • 业务流程:
事件 操作 结果
初始化数据事件 初始化数据 保存到缓存
中间点更新事件1 获取缓存更新数据1 更新缓存
中间点更新事件2 获取缓存更新数据2 更新缓存
中间点更新事件3 获取缓存更新数据3 更新缓存
中间点更新事件n 获取缓存更新数据n 更新缓存
结束事件 业务操作 落库,删除缓存
以上流程如果只是 OldEntity 转 NewEntity 是没有问题的,但是我们线上服务器是多台,发布的时候是一台台发布的,这个时候就会存在一个没有想到的情况。旧数据 OldEntity 在新发布的应用上被转化为新数据模型 NewEntity 后被保存在Redis,下一个中间点更新事件的请求打到了还没来得及发布的服务器上,这时旧版本的应用获取缓存时将 NewEntity 转 OldEntity 模型,转化失败,返回 null。导致线上报错预警。
  • 发布部分服务器后的业务流程:
事件 操作 结果 Redis数据模型
初始化数据事件 旧应用初始化数据 保存到缓存 OldEntity
中间点更新事件1 新版本应用更新数据 更新缓存 NewEntity
中间点更新事件2 旧版本应用更新数据 数据转化失败,报错 NewEntity

二 解决方案

不新建实体类,在旧的实体类模型上增加新属性:
class OldEntity {
    // 旧的属性
    private Integer age;
    
    // 新增属性
    private String name;
}
获取缓存后判断新增属性值是否为空,以此判断是否是旧应用保存的数据:
Map<byte[], byte[]> loadedHash = stringRedisTemplate.execute((RedisCallback<Map>) conn -> conn.hGetAll(key.getBytes()));
// private final static ObjectHashMapper SELECTIVE_MAPPER = new ObjectHashMapper();
Object cached = SELECTIVE_MAPPER.fromHash(loadedHash);

if (cached == null)
    return null;

OldEntity result = (OldEntity) cached;
if (ObjectUtils.isEmpty(result.getName())) {
    // 旧应用保存的数据
    // TODO 业务操作
} else {
    // 新应用保存的数据
    // TODO 业务操作
}

return result;
扫码关注有惊喜

(转载本站文章请注明作者和出处 qbian)

暂无评论

Copyright 2016 qbian. All Rights Reserved.

文章目录