異常背景
- 通過有效期的截止時間減去當前時間獲取緩存生效時間
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