赤壁网站制作,南通网站,苏州网站开发建设电话,动漫设计与制作专业就业方向善于总结#xff0c;才能更快进步通常#xff0c;我们队高并发的数据都会进行缓存#xff0c;而且为了防止缓存过大#xff0c;通常我们都会把缓存设置一个超时时间#xff0c;并且会有cache miss机制。本文#xff0c;我记录一下错误的缓存机制引起的BUG。起因好好的一个…善于总结才能更快进步通常我们队高并发的数据都会进行缓存而且为了防止缓存过大通常我们都会把缓存设置一个超时时间并且会有cache miss机制。本文我记录一下错误的缓存机制引起的BUG。起因好好的一个国庆自己完全没歇停让我给毁了。线上一次cache miss导致缓存数据错误便一直在查因。然后重写代码、测试、上线。emmm......直接看代码当然是伪代码了cache new cache();data cache.getData();if(isempty(data)) {data getDataFromResource()if(!isempty(data)) {cache.setData(data)}}看上去没错哈一般我们处理缓存的确是用这个步骤:读取缓存若cache miss(超时、网络原因)从数据源读取缓存重新设置缓存正常来说这样的确是没问题的。但是请接着往下看。资源类大致是这样的//上文getDataFromResource() 就是本类中读取数据class resource{private static connection new Connection();public static getConnection() {return connection;}public getData() {try{//todo:do anythingsdata connection.get();return data;}catch(e){return null;}}}而我的缓存类是基于资源类的class cache extends resource {}就是说我缓存类依赖的连接资源也是我原始资源的来源。事故原因当其中某次请求发生错误的时候(比如连接不可用网络卡顿丢包等等)资源类中的基类方法请求失败因此返回了NULL。 可能会感觉很奇怪啊明明我有空校验。但是业务是复杂的缓存的数据是从多方资源获取而来因此上文getDataFromResource()方法并不为空而是有部分数据存在。因此导致了缓存只将部分数据写入失败解决方式不要信任数据源一定是正确的要考虑数据源可能存在不正确的方式(目前处理方式)if(isempty(data)) {data getDataFromResource()if(!isempty(data)) {//todo:增加数据校验if(isValid(data)) {cache.setData(data)}else{//todo:发送邮件通知告诉开发数据可能不稳定mail.send();//todo:抛出异常控制器处理本次请求失败throw Exception();}}}或者提前计算好缓存本次cache miss直接抛出异常不需要计算考虑复杂的逻辑