ingenerator / runsingle
确保脚本在多个实例中只运行一次的包装包。
Requires
- php: ^7.2
- psr/log: ~1.0
Requires (Dev)
- bossa/phpspec2-expect: ^1.0
- phpspec/phpspec: ^2.0
- phpspec/prophecy: ^1.1
This package is auto-updated.
Last update: 2022-03-09 11:14:23 UTC
README
此包于2022年3月9日被弃用,将不再维护。截至该日期之前,它仍在工作并被使用。如果仍然需要,可以考虑分叉。同样,现在有许多支持的通用锁定包(例如symfony/lock)可供选择,如果需要运行的任务是PHP进程,这些包可能适合。
RunSingle
... 是一个锁定包装器,以确保在任何给定时间跨多个实例只运行一次命令。锁定通过远程主机上的数据库执行。
安装和构建数据库
克隆或下载此存储库,或者只需将其添加到您的 composer.json 中。
{ "require": { "ingenerator/RunSingle" : "0.*" } }
您需要 php。
初始数据库配置
对于标准驱动程序,RunSingle 需要访问包含以下字段的 MySql 数据库表。
CREATE TABLE IF NOT EXISTS locks ( task_name varchar(255), lock_timestamp int, timeout int, lock_holder varchar(255), PRIMARY KEY (task_name) );
在每个实例的项目根目录中创建一个名为 'run_single_config.php' 的文件。此文件应返回一个 LockDriver。您可以通过传递给 DbDriverFactory 的凭据来返回标准数据库驱动程序,例如。
<?php return Ingenerator\RunSingle\DbDriverFactory::factory(array( 'dsn' => 'mysql:host=localhost;dbname=run_single_db', 'db_user' => 'root', 'db_pass' => '', 'db_table_name' => 'locks', ));
运行任务
使用提供的包装脚本与标准驱动程序
bin/run_single.php --task_name=<task_name> --timeout=<timeout_in_seconds> -- <command>
参数
--task_name=<task_name>
value 是锁的标识符。选择一个独特、理想的是简短但有说明性的标题(它必须在所有实例中相同)。
--timeout=<timeout_in_seconds>
锁将授权的时间(以秒为单位)。它必须大于命令最坏情况下的(最长)运行时间。一个好的经验法则是将其设置为可以承受的最长时间间隔。此策略还旨在最大限度地提高对命令真正完成的信心。
-- <command>
要运行的命令。确保在命令前后都有一个双破折号,否则包装器无法安全地区分您的命令和它的参数。命令参数将被自动转义,因此只需像在 shell 中一样在 " -- " 后面输入命令即可。
可选参数
--no-garbage-collect
添加此选项以使 RunSingle 不会自动从锁存储中清除过时的条目。这通常适用于高度并发的设置。在所有实例中禁用垃圾收集(除了一个之外)。在所有实例上使用 --no-garbage-collect 意味着锁永远不会被清除。
命令输出 ...
打印到 STDOUT/STDERR,因为实际的脚本执行是通过 system() 完成的。
在您自己的类中使用LockDriver
$lock_driver = new \Ingenerator\RunSingle\DbDriver; $lock_id = $lock_driver->get_lock($task_name, $timeout, $garbage_collect); if ($lock_id) { // do your stuff $lock_driver->release_lock($task_name, $lock_id); }
自定义驱动程序
为了使用其他存储来锁定(不同的数据库系统、memcached,甚至是文件系统),RunSingle 需要传递一个实现 LockDriver 接口的替代驱动程序。
使用 run_single_config.php 返回您的驱动程序类的一个实例(工厂是一个方便的方式来做到这一点,但并非强制性的)。