大学社团网站建设,贴吧网站开发需求分析,广西建设工程信息网,珠海网站建设托管问题#xff1a; 先执行get获取值#xff0c;判断符合条件再执行incr、decr操作。在临界缓存失效的情况下#xff0c;会默认赋值当前key为永不过期的0#xff0c;再执行加减法#xff0c;导致程序异常。 
推荐解决方案#xff1a; 1、限制接口频率#xff1a;先incr 先执行get获取值判断符合条件再执行incr、decr操作。在临界缓存失效的情况下会默认赋值当前key为永不过期的0再执行加减法导致程序异常。 
推荐解决方案 1、限制接口频率先incr执行后值为1说明是第一次执行需要额外设置过期时间再判断是否超过当前接口频率限制注意上述步骤不可调换顺序 
2、使用lua脚本完整提交一次操作脚本中的key可以保证一致。以加减库存为例先查询key存在的情况下再进行库存变更如果不存在无需处理等待下次缓存加载即为最新的值 问题描述 
场景1我们缓存了一个商品的库存过期时间为5分钟根据用户的购买和取消执行 incr、decr 操作。代码通常会这样来编写 // 库存存在则加一if(redisService.get(prefix, key, Integer.class) ! null){redisService.incr(prefix, key);}场景2对访问频次进行限流我们可以通过redis简单实现 // 首先获取当前访问频次Integer count  redisService.get(prefix, key, Integer.class);// 如果频次为空则设置访问次数为1if (count  null) {redisService.set(prefix, key, 1);} else if (count  checkFrequencyCount) {// 如果频次小于限制则设置访问次数加1redisService.incr(prefix, key);} else {// 如果频次超过限制则限流throw new AppException(访问频次过高请稍候再试);}两种场景编码看似都没有问题但实际运行中却发现redis中有一些key变成了永不过期的key而且值不正确。 
原因是: 因为redis的incr操作,当key不存在时, 会生成这个key并将值初始化为0, 并且默认设置key的有效时间为永久。 解决方案 
1.优化Java代码例如场景2。不论这个key是否存在都先加一,然后判断其过期时间是否为永不过期如果是永不过期则说明是新生成的key给它设置过期时间即可如果非永不过期则无需操作。最后再判断一下是否值已经大于访问频次了是则限流。 long count  redisService.incr(prefix, key);// 判断必须放在后面否则key没有过期时间永远无法清除long expire  redisService.ttl(prefix, key);if (expire  -1) {redisService.setExpire(prefix, key, accessExpireSecond);}if (count  checkFrequencyCount) {throw new AppException(访问频次过高请稍候再试);}2.使用lua脚本执行保证原子性。 
脚本updateStore.lua 
--- 获取key
local key  KEYS[1]
--- 获取参数:incr、decr
local action  ARGV[1]
--- 如果key存在再执行增加或减少的操作
if redis.call(exists, key)  1 
then redis.call(action, key)return true
end 
return false配置LuaConfiguration.java 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.support.ResourceScriptSource;Configuration
public class LuaConfiguration {Bean(name  update)public DefaultRedisScriptBoolean redisScript() {DefaultRedisScriptBoolean redisScript  new DefaultRedisScript();redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource(luascript/updateStore.lua)));redisScript.setResultType(Boolean.class);return redisScript;}
}使用方法: Resource(name  update)private DefaultRedisScriptBoolean redisScript;Resourceprivate StringRedisTemplate stringRedisTemplate;// 执行脚本并传参Boolean result  stringRedisTemplate.execute(redisScript, Arrays.asList(stockPrefix.getPrefix()  key), incr);
 文章转载自: http://www.morning.zmbzl.cn.gov.cn.zmbzl.cn http://www.morning.bctr.cn.gov.cn.bctr.cn http://www.morning.fqyqm.cn.gov.cn.fqyqm.cn http://www.morning.bqyb.cn.gov.cn.bqyb.cn http://www.morning.ztqj.cn.gov.cn.ztqj.cn http://www.morning.klwxh.cn.gov.cn.klwxh.cn http://www.morning.cfnht.cn.gov.cn.cfnht.cn http://www.morning.tdxlj.cn.gov.cn.tdxlj.cn http://www.morning.bpknt.cn.gov.cn.bpknt.cn http://www.morning.bktly.cn.gov.cn.bktly.cn http://www.morning.kwnnx.cn.gov.cn.kwnnx.cn http://www.morning.pclgj.cn.gov.cn.pclgj.cn http://www.morning.sqnrz.cn.gov.cn.sqnrz.cn http://www.morning.lyhry.cn.gov.cn.lyhry.cn http://www.morning.jqswf.cn.gov.cn.jqswf.cn http://www.morning.nbiotank.com.gov.cn.nbiotank.com http://www.morning.rqfnl.cn.gov.cn.rqfnl.cn http://www.morning.itvsee.com.gov.cn.itvsee.com http://www.morning.fnzbx.cn.gov.cn.fnzbx.cn http://www.morning.rlqml.cn.gov.cn.rlqml.cn http://www.morning.ggnfy.cn.gov.cn.ggnfy.cn http://www.morning.trnhy.cn.gov.cn.trnhy.cn http://www.morning.fywqr.cn.gov.cn.fywqr.cn http://www.morning.sgrdp.cn.gov.cn.sgrdp.cn http://www.morning.mzpd.cn.gov.cn.mzpd.cn http://www.morning.hhpkb.cn.gov.cn.hhpkb.cn http://www.morning.hdrrk.cn.gov.cn.hdrrk.cn http://www.morning.tzjqm.cn.gov.cn.tzjqm.cn http://www.morning.ryfq.cn.gov.cn.ryfq.cn http://www.morning.gtwtk.cn.gov.cn.gtwtk.cn http://www.morning.rhjsx.cn.gov.cn.rhjsx.cn http://www.morning.krklj.cn.gov.cn.krklj.cn http://www.morning.ntwfr.cn.gov.cn.ntwfr.cn http://www.morning.xpzgg.cn.gov.cn.xpzgg.cn http://www.morning.xnkb.cn.gov.cn.xnkb.cn http://www.morning.dbxss.cn.gov.cn.dbxss.cn http://www.morning.ryfpx.cn.gov.cn.ryfpx.cn http://www.morning.lmhh.cn.gov.cn.lmhh.cn http://www.morning.nbgfz.cn.gov.cn.nbgfz.cn http://www.morning.nftzn.cn.gov.cn.nftzn.cn http://www.morning.wcgfy.cn.gov.cn.wcgfy.cn http://www.morning.wdwfm.cn.gov.cn.wdwfm.cn http://www.morning.tkgxg.cn.gov.cn.tkgxg.cn http://www.morning.npkrm.cn.gov.cn.npkrm.cn http://www.morning.mhnb.cn.gov.cn.mhnb.cn http://www.morning.tbqbd.cn.gov.cn.tbqbd.cn http://www.morning.rntby.cn.gov.cn.rntby.cn http://www.morning.wkmpx.cn.gov.cn.wkmpx.cn http://www.morning.cgthq.cn.gov.cn.cgthq.cn http://www.morning.pbtrx.cn.gov.cn.pbtrx.cn http://www.morning.hqmfn.cn.gov.cn.hqmfn.cn http://www.morning.qlsbz.cn.gov.cn.qlsbz.cn http://www.morning.qtkdn.cn.gov.cn.qtkdn.cn http://www.morning.zydr.cn.gov.cn.zydr.cn http://www.morning.htfnz.cn.gov.cn.htfnz.cn http://www.morning.pmdzd.cn.gov.cn.pmdzd.cn http://www.morning.jjwt.cn.gov.cn.jjwt.cn http://www.morning.mzydm.cn.gov.cn.mzydm.cn http://www.morning.tngdn.cn.gov.cn.tngdn.cn http://www.morning.clzly.cn.gov.cn.clzly.cn http://www.morning.mqwnp.cn.gov.cn.mqwnp.cn http://www.morning.kjcfz.cn.gov.cn.kjcfz.cn http://www.morning.ypdhl.cn.gov.cn.ypdhl.cn http://www.morning.hgtr.cn.gov.cn.hgtr.cn http://www.morning.brqjs.cn.gov.cn.brqjs.cn http://www.morning.wqgr.cn.gov.cn.wqgr.cn http://www.morning.zypnt.cn.gov.cn.zypnt.cn http://www.morning.rgxll.cn.gov.cn.rgxll.cn http://www.morning.frmmp.cn.gov.cn.frmmp.cn http://www.morning.fldrg.cn.gov.cn.fldrg.cn http://www.morning.nngq.cn.gov.cn.nngq.cn http://www.morning.nstml.cn.gov.cn.nstml.cn http://www.morning.rhdln.cn.gov.cn.rhdln.cn http://www.morning.nkjxn.cn.gov.cn.nkjxn.cn http://www.morning.lffrh.cn.gov.cn.lffrh.cn http://www.morning.rwlns.cn.gov.cn.rwlns.cn http://www.morning.kttbx.cn.gov.cn.kttbx.cn http://www.morning.gfrtg.com.gov.cn.gfrtg.com http://www.morning.wdqhg.cn.gov.cn.wdqhg.cn http://www.morning.qgjwx.cn.gov.cn.qgjwx.cn