設置key凌晨過期的思路
- 設置key的值的時候,計算下當前時間到第二天凌晨的時間差,設置key的過期時間。
- 利用定時任務,每天凌晨將需要過期的key刪除。
應用場景
- 按天為維度,限制用戶對資源的訪問次數。
- 按天為維度,生成遞增序列號。
代碼示例
/** * 按用戶id和天為維度生成遞增的單號 * * @return */ private String createNo(Integer userId) { StringBuilder sb = new StringBuilder(); String dateStr = DateUtils.getDateForFormat(new Date(), "yyyyMMdd"); sb.append("P").append(dateStr).append(userId); String keyPrefix = sb.toString(); long keySuffix = jedis.incr(keyPrefix); if (keySuffix > Constant.NO_MAXVALUE_999) { log.error("生成單號失敗,序號大於999,userId:" + userId); throw new RuntimeException("生成預約單號失敗,序號大於999"); } Long expiresTime = getSecondsNextEarlyMorning(); jedis.setExpire(keyPrefix, expiresTime.intValue()); String keySuffixStr = String.format("%03d", keySuffix); return keyPrefix + keySuffixStr; } /** * 判斷當前時間距離第二天凌晨的秒數 * * @return 返回值單位為[s:秒] */ public Long getSecondsNextEarlyMorning() { Calendar cal = Calendar.getInstance(); cal.add(Calendar.DAY_OF_YEAR, 1); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.MILLISECOND, 0); return (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000; }