高可用缓存

说起缓存大家并不默生,今天就有一段实际代码来给大家讲讲如何写一段简单高可用代码

@overwride
public UserInfo searchUser(String userNo){
    UserInfo user = dao.get(userNo);
    return user;
}

就这一行代码,也许做为初缓程序员来说是一行最简单不过的了。但是对于我们中级程序员来说,就要把这一行代码进行升级,会写成如下代码:

@Override
public UserInfo searchUser(String userNo){
    String key = "user_" + userNo;
    String userStr = redis.get(key);
    if(StringUtils.isNotBlack(userStr)){
        return JsonUtils.toBean(userStr, UserInfo.class);
    }
    UserInfo user = dao.get(userNo);
    if(user != null){
        redis.set(key, JsonUtils.toJson(user));
    }
    return user;
}

这种代码可能现在普遍程序员的写法,但是就偏偏最普通的代码往往埋下了黑手,当并发很高的时候会击穿缓存,而直接读取数据库,这样对数据库造成很大压力。所以就会产生下面代码

@Override
public synchronized UserInfo searchUser(String userNo){
    String key = "user_" + userNo;
    String userStr = redis.get(key);
    if(StringUtils.isNotBlack(userStr)){
        return JsonUtils.toBean(userStr, UserInfo.class);
    }
    UserInfo user = dao.get(userNo);
    if(user != null){
        redis.set(key, JsonUtils.toJson(user));
    }
    return user;
}

这样好是好,但是这个有个排队锁,也就是整个查询性能会大大下降,对于查询缓存也进行了排队,所以对这段代码再次进行升级

@Override
public UserInfo searchUser(String userNo){
    String key = "user_" + userNo;
    String userStr = redis.get(key);
    if(StringUtils.isNotBlack(userStr)){
        return JsonUtils.toBean(userStr, UserInfo.class);
    }
    synchronized(this){
        UserInfo user = dao.get(userNo);
        if(user != null){
            redis.set(key, JsonUtils.toJson(user));
        }
    }
    return user;
}

这样是不是感觉很好,但是这个也同样存在问题,原因就在高并发下排队读取了数据库,对数据库造成压力。所以需要再次升级

@Override
public UserInfo searchUser(String userNo){
    String key = "user_" + userNo;
    String userStr = redis.get(key);
    if(StringUtils.isNotBlack(userStr)){
        return JsonUtils.toBean(userStr, UserInfo.class);
    }
    synchronized(this){
        String userStr = redis.get(key);
        if(StringUtils.isNotBlack(userStr)){
            return JsonUtils.toBean(userStr, UserInfo.class);
        }
        UserInfo user = dao.get(userNo);
        if(user != null){
            redis.set(key, JsonUtils.toJson(user));
        }
    }
    return user;
}

这样已经接近完美,但是程序员不能每天的经历是写一堆关于没用的代码。那我们就用模板方式实现。

@Override
public UserInfo searchUser(String userNo){
    String key = "user_" + userNo;
    return redisCacheTemplate.find(key, 10000L, UserInfo.class, new CacheLoadable<UserInfo>() {
            @Override
            public UserInfo load() {
                return dao.get(userNo);
            }
        });
}
是不是很简单,具体Template实现可加微信
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值