ShedLockによる分散型タイミングタスクの繰返し実行の問題の解決

4185 ワード

複数のサービスインスタンスコードは同じであり、タイミングタスクも自然に同じです.負荷等化は実行時に,あるノードに到達するとタイミングタスクが実行され,制御可能な考え方はキューを用いて操作することである.
既存の考え方には以下の2つがあります.
  • は、負荷等化のタイミングタスクを、従来の直接実行トラフィックロジックから、まずトラフィックロジックをキューに要求し、その後、空きマイクロサービスをキューに自動的に受け取るように変更する.
  • 負荷等化のタイミングタスクをロックして操作する.

  • 今日お話しするShedLockは第2の考え方を実現する一つの方法であり、ShedLockは非侵入プログラミングの思想を採用し、注釈の方式を通じて相応の機能を実現する.
    ShedLock
    ShedLockは、分散環境で使用される複数のインスタンスの同じタイミングタスクが同じ時点で繰り返し実行される問題を解決するための、分散環境で使用されるタイミングタスクフレームワークです.
    解決策は、共通のデータベース内のテーブルを記録およびロックすることによって、同じ時点で最初の実行タイミングタスクのみが実行され、データベーステーブルに対応するレコードを書き込むノードが正常に実行され、他のノードが直接タスクをスキップするようにすることです.
    もちろんデータベースだけでなく、現在実装されているサポートデータストレージタイプには、従来のリレーショナル・データベースに加えて、MongoDB、Zookeeper、Redis、Hazelcastが含まれています.
    使用
    
      net.javacrumbs.shedlock
      shedlock-spring
      0.18.2
    
    import net.javacrumbs.shedlock.core.SchedulerLock;
    
    @Scheduled(cron = "0 0/10 0 * * ?")
    @SchedulerLock(name = "scheduledTaskName", lockAtMostFor = 60 * 1000, lockAtLeastFor = 60 * 1000)
    public void scheduledTask() {
       System.out.println("scheduledTask");
    }

    task 
    @Bean
    public ScheduledLockConfiguration taskScheduler(LockProvider lockProvider) {
        return ScheduledLockConfigurationBuilder
            .withLockProvider(lockProvider)
            .withPoolSize(10)
            .withDefaultLockAtMostFor(Duration.ofMinutes(10))
            .build();
    }
    
    
    @Bean
    public TaskScheduler taskScheduler(ScheduledExecutorService executorService, LockProvider lockProvider) {
        return SpringLockableTaskSchedulerFactory.newLockableTaskScheduler(executorService, lockProvider, Duration.of(10, MINUTES));
    }

    @SchedulerLock注記
  • name:異なるサービスを区別する識別としてデータベースに書き込むために使用されるタイミングサービスの名前を表示し、複数の同名のタイミングタスクがある場合、同じ時点で
  • が成功したのは1つだけです.
  • lockAtMostFor:タスクを正常に実行したノードが独占ロックを持つ最長時間、単位はミリ秒ms
  • lockAtMostForString:タスクが正常に実行されたノードが所有できる独占ロックの最長時間の文字列表現.例えば「PT 14 M」は14分
  • と表す.
  • lockAtLeastFor:タスクを正常に実行したノードが独占できる最短時間、単位はミリ秒ms
  • lockAtLeastForString:タスクが正常に実行されたノードが持つことができる排他的ロックの最短時間の文字列表現、例えば「PT 14 M」は14分
  • で表される.
    ロックの設定
    Mongo
    
        net.javacrumbs.shedlock
        shedlock-provider-mongo
        0.18.2
    
    @Bean
    public LockProvider lockProvider(MongoClient mongo) {
        return new MongoLockProvider(mongo, "databaseName");
    }
    

    JdbcTemplate
    CREATE TABLE shedlock(
      name VARCHAR(64), 
      lock_until TIMESTAMP(3) NULL, 
      locked_at TIMESTAMP(3) NULL, 
      locked_by  VARCHAR(255), 
      PRIMARY KEY (name)
    )
    
        net.javacrumbs.shedlock
        shedlock-provider-jdbc-template
        0.18.2
    
    @Bean
    public LockProvider lockProvider(DataSource dataSource) {
        return new JdbcTemplateLockProvider(dataSource);
    }
    

    ZooKeeper 
    
        net.javacrumbs.shedlock
        shedlock-provider-zookeeper-curator
        0.18.2
    
    @Bean
    public LockProvider lockProvider(org.apache.curator.framework.CuratorFramework client) {
        return new ZookeeperCuratorLockProvider(client);
    }

    Redis
    
        net.javacrumbs.shedlock
        shedlock-provider-redis-spring
        0.18.2
    
    @Bean
    public LockProvider lockProvider(JedisPool jedisPool) {
        return new RedisLockProvider(connectionFactory, ENV);
    }

    Redis (using Jedis)
    
        net.javacrumbs.shedlock
        shedlock-provider-redis-jedis
        0.18.0
    
    @Bean
    public LockProvider lockProvider(JedisPool jedisPool) {
        return new JedisLockProvider(jedisPool, ENV);
    }