Spring Cloud分佈式定時器之ShedLock的實現

在實際的項目開發工作中,我們經常會遇到需要做一些定時任務的工作,那麼在Spring Cloud中是如何實現的?今天來介紹下其中的一種解決方案——輕量級分佈式定時鎖ShedLock

ShedLock

ShedLock是一個在分佈式環境中使用的定時任務框架,用於解決在分佈式環境中的多個實例的相同定時任務在同一時間點重復執行的問題。

解決思路是通過對公用的數據庫中的某個表進行記錄和加鎖,使得同一時間點隻有第一個執行定時任務並成功在數據庫表中寫入相應記錄的節點能夠成功執行而其他節點直接跳過該任務。
目前已經實現的支持數據存儲類型不僅僅隻有關系型數據庫,還包括MongoDB,Zookeeper,Redis,Hazelcast。

1. pom文件添加相關依賴

在pom文件中添加shedLock相關依賴

 <!--shedlock-->
    <dependency>
      <groupId>net.javacrumbs.shedlock</groupId>
      <artifactId>shedlock-spring</artifactId>
      <version>2.2.0</version>
    </dependency>
    <dependency>
      <groupId>net.javacrumbs.shedlock</groupId>
      <artifactId>shedlock-provider-jdbc-template</artifactId>
      <version>2.2.0</version>
    </dependency>

2. 添加相關配置

在啟動類添加@EnableScheduling和@EnableSchedulerLock(defaultLockAtMostFor = “PT30S”)註解,表示要啟動ShedLock定時任務

defaultLockAtMostFor要設置值,不設置會報錯;設置值一般設置比定時任務大點值,一般在每個定時任務中都會配置defaultLockAtMostFor值,會覆蓋啟動類中的值

@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "PT30S")
public class OneStopServiceApplication {
  public static void main(String[] args) {
    SpringApplication.run(OneStopServiceApplication.class, args);
  }

}

3.添加ShedLock配類

shedLock支持關系型數據庫,以mysql為例,配置mysql以及表名;shedLock默認表名為shedlock,可以設置自定義表名。

@Configuration
public class ScheduledLockConfig {
  @Bean
  public LockProvider lockProvider(DataSource dataSource) {
    //自定義表名
    return new JdbcTemplateLockProvider(dataSource,"ccsy_shedlock");
  }
}

4.ShedLock定時任務

@Component
public class HourTask {
  /**
   * 最小鎖定時間,一般設置成定時任務小一點
   */
  private static final int MIN_LOCK_TIME = 1000;//單位毫秒
  /**
   * 最大鎖定時間,一般設置成比正常執行時間長的值
   */
  private static final int MAX_LOCK_TIME = 1000 * 2;//單位毫秒

  
  @Scheduled(cron = "0/1 * * * * ? ")
  @SchedulerLock(name = "測試", lockAtMostFor = MAX_LOCK_TIME, lockAtLeastFor = MIN_LOCK_TIME)
  public void visitCountTaskByTwoHour() {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    System.out.println("現在時間是" + format.format(new Date())+ Thread.currentThread().getName());
  }
}

@SchedulerLock註解一共支持五個參數,分別是

  • name 用來標註一個定時服務的名字,被用於寫入數據庫作為區分不同服務的標識,如果有多個同名定時任務則同一時間點隻有一個執行成功
  • lockAtMostFor 成功執行任務的節點所能擁有獨占鎖的最長時間,單位是毫秒ms
  • lockAtMostForString 成功執行任務的節點所能擁有的獨占鎖的最長時間的字符串表達,例如“PT14M”表示為14分鐘
  • lockAtLeastFor 成功執行任務的節點所能擁有獨占所的最短時間,單位是毫秒ms
  • lockAtLeastForString 成功執行任務的節點所能擁有的獨占鎖的最短時間的字符串表達,例如“PT14M”表示為14分鐘

5.創建mysql數據庫中定時任務ccsy_shedlock表

CREATE TABLE ccsy_shedlock (
 NAME VARCHAR ( 64 ),
 lock_until TIMESTAMP ( 3 ) NULL,
 locked_at TIMESTAMP ( 3 ) NULL,
locked_by VARCHAR ( 255 ),
PRIMARY KEY ( NAME ))

到此這篇關於Spring Cloud分佈式定時器之ShedLock的實現的文章就介紹到這瞭,更多相關Spring Cloud分佈式定時器內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: