0

我有两个或更多 PHP 应用程序在 Docker 上运行,它们处理共享目录中的文件。所以我需要一个锁定系统来防止这些应用程序在同一个文件上工作。例如:目录中有3个文件,如果app1在file1上工作,app2必须跳过这个file1并传递给file2。我在应用程序中有这样的脚本:

// $files is a list of all files in the directory
foreach($files as $file) {
    $this->performFile($file);
    $this->moveFileToHistory($file);
}

我尝试使用文件或目录作为锁,例如,如果 file1.lock(file or directory) 存在,它就会被锁定。

$dir = md5($file) . 'lock';

if (@mkdir($dir, 0700)) {
    $this->performFile($file);
    $this->moveFileToHistory($file);
    rmdir($dir);
}

它可以工作,但如果发生崩溃或中断,我认为最好使用即使 PHP 本身崩溃也可以清理或释放的东西。所以我在考虑:

  • 信号量,但它不起作用,因为每个应用程序都在 Docker 上运行,进程是隔离的,对吧?
  • 在端口上打开一个套接字,如果该端口已经打开,则它被锁定。但是我们有几个文件要处理,并且文件的数量不固定。我们该如何处理呢?

在这种情况下,有没有比使用文件或目录更好的方法?

4

1 回答 1

0

我终于想出了一个解决方案。来自 symfony的这个组件symfony/lock可以用来管理锁。您可以定义完全符合我需要的过期时间。这里有一个例子:

foreach($files as $file) {
  // the lock expires after 60s if $lock->release() is not called due to a randomly reason.
  $lock = $this->lockFactory->createLock(md5($file), 60);
  if (!$lock->acquire()) {
    continue;
  }

  try {
    $this->performFile($file);
    $this->moveFileToHistory($file);
  } finally {
    $lock->release();
  }
}

您可以使用那些可用的商店来管理锁。

于 2021-08-11T06:34:48.823 回答