美文网首页Java
不同用户看到了相同的信息-一次web系统缓存问题的解决

不同用户看到了相同的信息-一次web系统缓存问题的解决

作者: 温苓 | 来源:发表于2017-12-24 16:00 被阅读6次

    最近负责的系统总是出现奇怪的缓存问题,在这里简单记录一下碰到的问题和踩到的坑。

    问题:用户反映使用不同账号A,B登录时,都出现账号A的页面信息(未邮寄账单提示)。如下所示:

    图1:未邮寄账单提示

    一  session缓存问题

    鉴于之前也出现过类似的session缓存问题,session的key信息未清除。

    如果A用户切换至B用户时,使用了不同的session key如‘U’,‘U_P’保存不同的信息,但是切换后只清除了'U'信息,忘记清除'U_P'信息,则可能导致A用户和B用户看到同样的‘U_P’信息。查看此处的代码也确实使用了seesion缓存:

    图2:未邮寄账单session缓存

    是不是这个原因引起的呢,之前的这个问题按说已经修复了,难道还有啥代码没改?查看代码,切换用户的时候移除了session的内容,登出账号的时候也失效掉了session信息。

    图3:session清除

    通过查看后台服务器日志,发现A用户登录后调用了/un-post-billls-GET链接,获取到了未邮寄账单信息。但是B用户的后台日志没有找到调用过后台的链接,所以排除了后台session缓存错误的可能。后台日志就不上图了,^_^。

    二 浏览器本地缓存问题

    由于B用户根本就没有调用后台服务,就拿到了未邮寄账单的信息,我们认为很大可能是浏览器本地缓存引起的问题。

    1 Localstorage缓存

    查看前端代码,在查询未邮寄账单信息时,使用了HTML5的window.localStorage来保存用户的信息,代码如下:

    图4:localstorage缓存

    并没有看到对localStorage的clear操作,这样可能是有问题的:A用户登录后在localstorage保存了未邮寄账单信息,切换至B用户后由于没有clear A用户的localstorage 信息。那么B用户就看到了A用户的本地缓存信息。

    解决办法:在合适的时机清理localstorage,使用不同的key 保存缓存信息。

    2 浏览器url缓存

    这个bug是否就这样解决了呢?仔细看图4的localstorage代码,A用户和B用户实际上使用了不同的dataKey_A与dataKey_B来保存各自的localStorage,虽然说有一定的安全问题,但是由于不同的KEY存在,按道理说B用户不会看到A用户的未邮寄账单信息。问题可能不在localStorage这里。

    根据 HTTP 规范,GET 用于信息获取,而且应该是幂等的。也就是说,当使用相同的URL重复GET请求会返回预期的相同结果。这个问题与现在的情况非常相似。

    查看代码,使用了相同的URL请求重复GET:

    图5:URL请求GET

    解决办法:

    1. GET请求URL后加随机数,让服务器认为不是相同的请求。

    例 “/un-post-bills?t=” + new Date().getTime()

    2. 使用POST代替GET,浏览器不会对POST做缓存

    三 总结

    WEB系统的缓存通常有好几级,本地缓存,服务器缓存,数据库缓存等。分析缓存问题时,要考虑每一层可能引起的问题,每一层的缓存技术也有很多种,要根据具体的场景来选择使用何种缓存技术。

    缓存技术博大精深,本文只记录寻找bug时涉及的技术,其他有待学习。

    相关文章

      网友评论

        本文标题:不同用户看到了相同的信息-一次web系统缓存问题的解决

        本文链接:https://www.haomeiwen.com/subject/nikhgxtx.html