warmans / dlock
此包最新版本(0.0.3)没有可用的许可证信息。
分布式锁库
0.0.3
2014-05-11 19:45 UTC
Requires
- php: >=5.3.0
Suggests
- ext-memcache: For memcache datastore
- ext-redis: For redis datastore
This package is not auto-updated.
Last update: 2024-09-28 16:03:07 UTC
README
PHP的分布式锁库。此库允许使用缓存服务器(Redis或Memcache)在多个服务器上锁定进程。
示例用例是您有一个必须发生的进程,例如每小时一次,但不能重复,例如导入。在这种情况下,您可以将导入作业设置在所有应用程序服务器上,但每小时只有一个(系统时钟最快的那个)能够获取锁,所以其他所有都会失败。如果任何服务器离线,另一个将获取锁,导入将像往常一样继续。
像大多数分布式系统一样,应保持服务器系统时钟的一致性。如果服务器的时钟比运行作业的时间更不一致,您可能仍然会重复作业。为了避免这种情况,您可以在某处存储作业的全局唯一标识符(例如,在redis集合中),并在锁定后简单地检查作业是否已经被执行(注意:不是在锁定之前,否则您会有竞争条件)。
使用原子函数实现锁定,以避免竞争条件。为了阻止用户创建自己的竞争条件,没有“isLocked”功能。您必须始终尝试创建锁以确定锁定状态。
用法
允许锁通过locked()方法自动处理锁定/解锁
//raw memcache connection $memcache = new \Memcache(); $memcache->connect('localhost'); //datastore adapter $adapter = new \Dlock\Datastore\Memcache($memcache); $lock = new \Dlock\Lock($adapter); $lock->locked(function(){ //do something });
或者自己管理
//raw memcache connection $memcache = new \Memcache(); $memcache->connect('localhost'); //datastore adapter $adapter = new \Dlock\Datastore\Memcache($memcache); $lock = new \Dlock\Lock($adapter); if ($lock->acquire()) { //do something $lock->release(); } else { //handle lock failure }
最后,如果您想等待锁可用,可以使用阻塞锁
//raw memcache connection $memcache = new \Memcache(); $memcache->connect('localhost'); //datastore adapter $adapter = new \Dlock\Datastore\Memcache($memcache); $lock = new \Dlock\Lock($adapter); //wait for up to 30 seconds for lock then return false if ($lock->acquire(30)) { //do something $lock->release(); } else { //handle lock failure } //or use closure with 30 second block $lock->locked(function(){ //do something }, 30);
选项
$lock = new Lock([...], [...], $options);
锁的构造函数的第三个可选参数是一个选项数组。选项如下
适配器
任何实现了DatastoreInterface接口的类都可以用作适配器
interface DatastoreInterface { public function acquireLock($lockId); public function releaseLock($lockId); }
包含的实现如下
Memcache
//raw memcache connection $memcache = new \Memcache(); $memcache->connect('localhost'); //configure adapter with localhost connction and an hour TTL on locks $adapter = new \Dlock\Datastore\Memcache($memcache, 3600);
Redis
//raw redis connection $redis = new \Redis(); $redis->connect('localhost'); //configure adapter with localhost connction and an hour TTL on locks $adapter = new \Dlock\Datastore\Redis($memcache, 3600);
运行测试
测试分为两个测试用例;单元和集成。集成测试需要在您的localhost上运行运行的Redis和Memcache服务器。
从根目录运行所有测试
phpunit
仅运行单元测试
phpunit --testsuite=unit
仅运行集成测试
phpunit --testsuite=integration