Redis解決分布式定時任務重復執行問題


問題描述: 有一個定時任務是每周一給客戶發送郵件的功能, 后台部署了2台服務器,所以客戶 收到了2封重復郵件。

解決思路:

分布式鎖一般有三種實現方式:1. 數據庫樂觀鎖;2. 基於Redis的分布式鎖;3. 基於ZooKeeper的分布式鎖。

這里使用一台Redis服務器來解決上面的問題。

代碼部分比較簡單:

加鎖 :主要是給多個定時任務給redis加鎖(key),如果存在key,則加鎖失敗,如果不存在,則嘗試去加鎖,返回加鎖結果。 

解鎖: 設置一下過期時間為20秒(可根據任務執行長短調整),過期后自動釋放掉。這里就不去代碼里面釋放鎖了。

private static final String LOCK_SUCCESS = "OK";
    private static final String SET_IF_NOT_EXIST = "NX";
    private static final String SET_WITH_EXPIRE_TIME = "PX";
    private static final Long RELEASE_SUCCESS = 1L;

 /**
     * 嘗試獲取分布式鎖
     *
     * @param jedis      Redis客戶端
     * @param lockKey    鎖
     * @param requestId  請求標識
     * @param expireTime 超期時間
     * @return 是否獲取成功
     */
    public static boolean tryGetDistributedLock(Jedis jedis, String lockKey, String requestId, int expireTime) {
    //這里的jedis自己去實現一下 String result
= jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime); if (LOCK_SUCCESS.equals(result)) { return true; } return false; }

 

測試 (同時啟動4個服務,每個服務上面啟動三個同樣的定時任務)

 //每分鍾執行一次
    static final String cron1 = "0 */1 * * * ?";

    @Scheduled(cron = cron1)
    public void testRedis1() {
        String msg = doRedis();
        System.out.println("msg1 :" + msg);
    }
    
    @Scheduled(cron = cron1)
    public void testRedis2() {
        String msg = doRedis();
        System.out.println("msg 2:" + msg);
    }
    
    @Scheduled(cron = cron1)
    public void testRedis3() {
        String msg = doRedis();
        System.out.println("msg 3:" + msg);
    }


    //執行redis
    private String doRedis() {
        boolean flag = RedisTool.tryGetDistributedLock("sendMail_20200101", UUID.randomUUID().toString(), 1000 * 20);
        String msg = null;
        if (flag) {
            msg = "你獲取到鎖了可以去操作業務!";
        } else {
            msg = "別人獲取到鎖了,你就不用操作了!!!!";
        }
        return msg;
    }

 

測試結果

 

 

觀察到每一分鍾, 3X4個定時任務中,只有一個能獲取到鎖,可以去操作業務,其他同樣的定時任務失敗了 。

 

總結:后面會具體總結一下分布式鎖相關的內容

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM