利用Redisson實現分布式延時任務排程功能

2021-10-10 18:42:45 字數 2627 閱讀 4190

定時任務是在編碼世界中經常遇到的問題,比如定時備份資料庫、定時重新整理快取等,可以通過linux定時任務完成,也可以通過框架如spring完成,但是在分布式場景中傳統單機可以完成功能就不太行了,所以需要借助其他工具來實現任務排程的功能

場景:在一些訂單場景中,使用者下單後會鎖定一些資源,然後使用者非正常退出(沒有觸發取消訂單操作),導致訂單資源占用無法釋放的問題。

借助工具:redisson分布式服務中的分布式排程任務服務(scheduler service)

定時執行具體任務,主要實現關單,釋放相關資源(優惠券等),設定相關狀態標誌位

注意:runnable、callable介面二選一,必須實現序列化字段,因為任務最終要被序列化儲存在redis中

@slf4j

@data

public class closeordertask implements runnable, serializable

//獲取到鎖,正常執行關單操作

log.info("get lock order:{} ", orderid);

orderdto order = orderservice.getorder(orderid);

if(orderdetails.getstatus() == orderstatus.new)

}catch (exception e)finally }}

}

註冊乙個任務排程器的bean

注意:bean的destory方法必須重寫,否則在進行關閉spring容器時,任務排程中心會被關閉,再次啟動後不會喚醒

/**

* 關單定時任務

*/@bean(destroymethod = "")

public rscheduledexecutorservice rscheduledexecutorservice(@autowired redissonclient redissonclient)

例子實現了兩個方法,開啟乙個定時任務和取消乙個定時任務。

因為定時任務的取消時通過taskid取消的,所以在提交任務或獲取taskid,並對orderid和taskid做了一下對映,在取消訂單的時候就比較容易了

@slf4j

@service

public class closeorderserviceimpl implements closeorderservice , taskid : {}", orderid, schedule.gettaskid());

}@override

public void cancelscheduleclosetask(string orderid) , taskid : {}", orderid, taskid);

if (!stringutils.isemptystr(taskid))}}

在使用者進行下單操作時可以提交乙個定時任務

在使用者取消訂單時可以取消orderid對應的定時任務

提交乙個任務後,redis中會新增4個鍵值對

提交乙個延時任務排程任務,會在:scheduler中產生兩條資料,分別是任務下一次執行時間和任務下一次執行時間+重試時間

spring在註冊executorservice時指定了工人(worker)的數量,會在本地起執行緒來執行這些待執行的任務。

1、任務過期,客戶端掛了,然後過一度時間重啟,任務是否還會執行。

客戶端重啟後,過期的任務都會被拿到客戶端裡面進行消費。

存在同時啟動多個客戶端,是否會發生任務搶占問題,內部是否有鎖機制?答案是會的

2、同乙個任務是否會被多個客戶端執行

通過兩台伺服器,每台提交10個任務,多輪測試沒有發生同乙個任務被多次執行的情況。

加上執行緒執行sleep後同樣進行測試,發現同一任務被不同客戶端消費,所以需要有鎖機制

3、任務(schedule 單次)執行完畢後,redis是否會刪除任務佇列中的任務

任務執行完畢後,會刪除tasks、scheduler中的任務,同時counter-1

4、任務佇列的過期策略

所有任務的過期時間都是-1(永不過期),保證任務不會丟

5、任務執行異常情況

能夠正常捕捉到異常,並進行處理,同時任務會從redis中刪除

Redisson實現分布式鎖

引入包 org.redissongroupid redissonartifactid 3.10.0version dependency redissonconfig類 package com.xiepanpan.locks.lockstest.config import org.redisson.r...

RedisSon實現分布式鎖

主要步驟 1 引入redisson的依賴 2 配置redisson的配置類 3 使用redisson構建分布式鎖,在需要使用分布式鎖的地方注入redissonclient這個類來獲取鎖 第一步 引入依賴 org.springframework.boot spring boot starter par...

redisson實現分布式鎖

redisson官方文件 1.匯入相關依賴 這裡我只匯入redisson,其他還需要redis的依賴 org.redisson groupid redisson artifactid 3.12 5 version dependency 2.新增redisson核心配置 description red...