Redisの一般的な用途

6847 ワード

一、グローバルID

    /** ID    */
    final static long maxNum = 2100000000;
    /**   ID */
    final static long startNum = 1000000000;
    /** redis   */
    final static long redisStepLength = 1;

    /**
     *   redis     (10   )
     * 
     * @return
     * @throws RedisException
     */
    private long getAtomicLong(String key) throws RedisException {

        try {
            //   redis key  
            RAtomicLong seqLong = redissonClient.getAtomicLong(key);
            if (seqLong.get() > maxNum || seqLong.get() < startNum) {
                seqLong.set(startNum);
                seqLong.expire(1, TimeUnit.DAYS);
            }
            seqLong.addAndGet(redisStepLength);
            return seqLong.get();
        } catch (Exception e) {
            log.error("  redis       : ", e);
            return RandomUtils.nextLong(startNum, maxNum);
        }
    }

    /**
     *      ID   
     * 
     * @param key
     *            redisKEY,   param1:param2:param3....
     * @return 6+10=16   
     * @throws RedisException
     */
    public Long getSeq_16(String key) throws RedisException {

        checkForKey(key);
        String DateKEY = DateFormatUtils.format(new Date(), "yyMMdd");
        return Long.valueOf(DateKEY + getAtomicLong(key + ":" + DateKEY));
    }

二、分布ロック
/**
     * when the time that thread execute business > leaseTime,it is not safe (maybe
     * others have already get the lock);
     * 
     * But we should not hold the lock all the time,setting leaseTime is necessary
     * 
     * 
     * @param key
     *            lockKey
     * @param waitTime
     *                   
     * @param leaseTime
     *                     
     * @param timeUnit
     *                
     * @throws RedisException
     *             throw when locked failed
     */
    public  T execute(String key, long waitTime, long leaseTime, TimeUnit timeUnit, LockCallback callback)
            throws RedisException {

        checkForKey(key);

        RLock rLock = redissonClient.getLock(key);
        if (StringUtils.isBlank(key) || waitTime <= 0 || leaseTime <= 0 || timeUnit == null) {
            throw new RedisException(RedisErrorCode.KEY_LOCKED_FAILED);
        }
        boolean isLocked = false;
        try {
            //      
            isLocked = rLock.tryLock(waitTime, leaseTime, timeUnit);

            if (!isLocked) {
                log.debug("locked failed ,key [{}]", key);
                throw new RedisException(RedisErrorCode.KEY_LOCKED_FAILED);
            }

            return callback.doWithLock();

        } catch (InterruptedException e) {
            log.debug("locked failed ,key [{}]: ", key, e);
            throw new RedisException(RedisErrorCode.KEY_LOCKED_FAILED);
        } finally {
            if (isLocked) {
                log.debug("Unlock {} ", key);
                rLock.unlock();
                log.debug("Unlock {} SUCCESS", key);
            }
        }
    }

分散ロックを呼び出す例

    public static void main(String[] args) {

        RedisUtils redisUtils = new RedisUtils();
        String response;
        try {
            redisUtils.execute("lock:key:seq", 3000, 4000, TimeUnit.MILLISECONDS, new LockCallback() {

                public String doWithLock() {

                    /*
                     * do business in Lock
                     */

                    return null;
                }

            });
        } catch (RedisException e) {

            /*
             * lock failed
             */
        }

    }