Docker 上的多个应用 运行 处理共享目录中的文件
Multiple apps running on Docker process files in shared directory
我在 Docker 上有两个或更多 PHP 应用程序 运行 处理共享目录中的文件。所以我需要一个锁定系统来防止这些应用程序处理同一个文件。
例如:目录中有 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(文件或目录)存在,它就会被锁定。
$dir = md5($file) . 'lock';
if (@mkdir($dir, 0700)) {
$this->performFile($file);
$this->moveFileToHistory($file);
rmdir($dir);
}
它可以工作,但如果发生崩溃或中断,我认为最好使用可以清理或释放的东西,即使 PHP 本身 crashes.So 我在想:
- 信号量,但它不起作用,因为每个应用程序都运行在 Docker 进程是隔离的,对吗?
- 在一个端口上打开一个套接字,如果这个端口已经打开,那么它就被锁定了。但是我们有几个文件要处理,文件的数量不是fixed.How,我们可以处理吗?
在这种情况下,还有比使用文件或目录更好的方法吗?
我终于想到了解决办法。
有一个来自 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();
}
}
您可以使用那些 available stores 来管理锁。
我在 Docker 上有两个或更多 PHP 应用程序 运行 处理共享目录中的文件。所以我需要一个锁定系统来防止这些应用程序处理同一个文件。 例如:目录中有 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(文件或目录)存在,它就会被锁定。
$dir = md5($file) . 'lock';
if (@mkdir($dir, 0700)) {
$this->performFile($file);
$this->moveFileToHistory($file);
rmdir($dir);
}
它可以工作,但如果发生崩溃或中断,我认为最好使用可以清理或释放的东西,即使 PHP 本身 crashes.So 我在想:
- 信号量,但它不起作用,因为每个应用程序都运行在 Docker 进程是隔离的,对吗?
- 在一个端口上打开一个套接字,如果这个端口已经打开,那么它就被锁定了。但是我们有几个文件要处理,文件的数量不是fixed.How,我们可以处理吗?
在这种情况下,还有比使用文件或目录更好的方法吗?
我终于想到了解决办法。 有一个来自 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();
}
}
您可以使用那些 available stores 来管理锁。