Spring Shedlock не обеспечивает синхронизацию - PullRequest
1 голос
/ 18 июня 2020

У меня есть следующее запланированное задание, которое выполняется в нескольких экземплярах.

@Scheduled(fixedRate = 10000)
@SchedulerLock(name = "AwesomeJob", lockAtLeastForString = "5S", lockAtMostForString = "5S")
public void awesomeJob() throws InterruptedException {

    for (int i = 0; i < 5; i++) {
        log.info("Processing {}", i);
        Thread.sleep(100000L);
    }
}

Я знаю, что если задача занимает больше времени, чем lockAtMostFor, результирующее поведение может быть непредсказуемым. Есть ли способ избежать такого поведения с помощью метода SimpleLock.extend? Я использую JdbcLockProvider. Я получил эту идею от https://github.com/lukas-krecan/ShedLock/issues/151.

Ответы [ 2 ]

1 голос
/ 19 июня 2020

Самый простой способ - установить lockAtMostFor на большее значение. Это просто безопасность net на случай, когда узел, выполняющий задачу, умирает, так что это не должно быть проблемой.

Если вы не можете сделать это по какой-либо причине, вы можете использовать метод extend, как описано в предоставленной вами проблеме. Но это означает, что вам придется управлять блокировкой вручную. В настоящее время нет функции, позволяющей расширить блокировку, созданную автоматически с помощью АОП.

1 голос
/ 18 июня 2020
interface LockService {
   bool aquireLock(String lockKey, String value);
   bool releaseLock(String lockKey);
}

interface SomeService {
   void do();
}

class Scheduler{
    @AutoWired LockService lockService;
    @Autowired SomeService someService;
    @Scheduled(fixedRate = 10000)
    public void awesomeJob() throws InterruptedException {
      if(lockService.aquireLock("awesomeJob", serverId) ){
        try{
           //call service method 
            someService.do();
        }catch( Exception e ){
          //TODO
        }finally{
          lockService.releaseLock("awesomeJob");
        }
      }   
    }
}

Вы можете иметь блокировку, подобную этому примеру, реализовать интерфейс блокировки, который будет обеспечивать блокировку для данной службы. Если у вас есть LockService, используйте его, чтобы ограничить запуск функции.

Единственная проблема в том, что вам нужно добавить этот блок кода ко всем функциям. Если вы не хотите добавлять этот блок кода ко всем функциям, добавьте обработчик AOP на основе аннотаций.

Кроме того, что делать, если сервер, получивший блокировку, умирает? Нам нужно установить максимальное время истечения каждой блокировки или использовать время в значении блокировки, чтобы определить, когда она была добавлена, на основе времени блокировки и принять решение, возможно ли это запустить или нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...