A.11 springboot 互斥定時(shí)任務(wù)

背景

當(dāng)我們的項(xiàng)目為了達(dá)到負(fù)載均衡或者備份的目的,服務(wù)通常會啟動兩個(gè)及以上的實(shí)例,但是如果服務(wù)中有定時(shí)任務(wù),定時(shí)任務(wù)又不需要啟動多個(gè),只需要單實(shí)例運(yùn)行,因此造成了矛盾。本主要講解水平擴(kuò)展后的服務(wù),如何做定時(shí)任務(wù)的單實(shí)例互斥運(yùn)行

環(huán)境

  • springboot:在springboot環(huán)境下
  • redis:配合redis進(jìn)行

思路

  1. 利用spring的@Scheduled機(jī)制在項(xiàng)目中開啟定時(shí)任務(wù)
  2. springboot集成redis后得到StringRedisTemplate
  3. 在定時(shí)任務(wù)執(zhí)行前獲取redis的鎖
  4. 判斷是否獲取到鎖?
  5. 如果獲取到鎖,設(shè)置鎖的有效期(防止程序意外停止),執(zhí)行任務(wù),最后釋放鎖
  6. 如果未獲取到鎖,表明鎖已經(jīng)被其他的服務(wù)實(shí)例搶走,實(shí)例放棄定時(shí)任務(wù)

關(guān)鍵代碼如下

/**
 * 分布式定時(shí)任務(wù)的測試
 * @author mateng
 */
@Component
public class SchedueService {
    
    private static final Logger logger = LoggerFactory.getLogger(SchedueService.class);
    
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    
    private final String key = "job";
    private final String value = "running";
    
    @Scheduled(fixedRate=2000)
    public void testaaa() {
        boolean lock = false;
        try {
            // 獲取鎖
            lock = stringRedisTemplate.opsForValue().setIfAbsent(key, value);
            logger.debug("是否獲取到鎖:" + lock);
            if (lock) {
                // 如果在執(zhí)行任務(wù)的過程中,程序突然掛了,為了避免程序因?yàn)橹袛喽斐梢恢奔渔i的情況產(chǎn)生,20分鐘后,key值失效,自動釋放鎖,
                stringRedisTemplate.expire(key, 20, TimeUnit.MINUTES);
                
                //執(zhí)行定時(shí)任務(wù)
                doSomething();
            } else {
                logger.debug("沒有獲取到鎖,不執(zhí)行任務(wù)!");
                return;
            }
        } finally {// 無論如何,最終都要釋放鎖
            if (lock) {// 如果獲取了鎖,則釋放鎖
                stringRedisTemplate.delete(key);
                logger.debug("任務(wù)結(jié)束,釋放鎖!");
            } else {
                logger.debug("沒有獲取到鎖,無需釋放鎖!");
            }
        }
    }

    private void doSomething() {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

展望

后期章節(jié)中將會講解真正的分布式定時(shí)任務(wù)的實(shí)現(xiàn),將一個(gè)定時(shí)任務(wù)拆解到多個(gè)服務(wù)中進(jìn)行同時(shí)的定時(shí)任務(wù)執(zhí)行

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容