异常背景
- 通过有效期的截止时间减去当前时间获取缓存生效时间
long seconds = bo.getEndTime().getTime() - System.currentTimeMillis();
- 在存储生效时间时,对时间Long进行强制转换时
(int)seconds
发生异常
异常原因
-
异常信息
redis.clients.jedis.exceptions.JedisDataException: ERR invalid expire time in setex at redis.clients.jedis.Protocol.processError(Protocol.java:115) ~[jedis-2.6.1.jar:na] at redis.clients.jedis.Protocol.process(Protocol.java:141) ~[jedis-2.6.1.jar:na] at redis.clients.jedis.Protocol.read(Protocol.java:196) ~[jedis-2.6.1.jar:na] at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:283) ~[jedis-2.6.1.jar:na] at redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:182) ~[jedis-2.6.1.jar:na] at redis.clients.jedis.Jedis.setex(Jedis.java:422) ~[jedis-2.6.1.jar:na]
异常分析
-
数值类型强制转换发生溢出,缓存失效时间为负数
-
bo.getEndTime().getTime() - System.currentTimeMillis(); // 得到 long 型数据 2169331921L // 再将 long 转 int 时,使用 (int) seconds 发生溢出 -2125635375 long seconds = 2169331921L; System.out.println((int) seconds); // -2125635375
Redis 失效时间赋值源码1
-
//如果定义了key的过期时间 if (expire) { //从expire对象中取出值,保存在milliseconds中,如果出错发送默认的信息给client if (getLongLongFromObjectOrReply(c, expire, &milliseconds, NULL) != C_OK) return; // 如果过期时间小于等于0,则发送错误信息给client if (milliseconds <= 0) { addReplyErrorFormat(c,"invalid expire time in %s",c->cmd->name); return; } //如果unit的单位是秒,则需要转换为毫秒保存 if (unit == UNIT_SECONDS) milliseconds *= 1000; }
缓存失效时间小于0时,抛出异常
- 失效时间 < 0 ,-1L