【问题标题】:Symfony lock component doesn't lock in productionSymfony 锁组件在生产中没有锁定
【发布时间】:2018-06-14 17:38:18
【问题描述】:

我升级到 Symfony 3.4.* 以利用新的锁组件。然而,它似乎在开发中工作,但在生产中总是获得锁。这是我的代码:

BaseCommandWrapper:

<?php
namespace CoreBundle\Command;

ini_set('max_execution_time', 3600); 

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Lock\Factory;
use Symfony\Component\Lock\Store\SemaphoreStore;

use Symfony\Component\Console\Command\LockableTrait;

class BaseCommandWrapper extends ContainerAwareCommand {

    use LockableTrait;

    function start($commandName) {

        $this->commandName = $commandName;

        $store = new SemaphoreStore();
        $factory = new Factory($store);

        $this->lock = $factory->createLock($this->commandName);

        if (!$this->lock->acquire()) {
            echo 'This command is already running in another process.' . PHP_EOL;
            return false;
        }

        echo "Lock aquired" . PHP_EOL;

        return $this->lock;
    }

    function stop() {

        echo "Releasing lock" . PHP_EOL;

        $this->lock->release();

    }

}


?>

命令本身:

class SomeCommand extends BaseCommandWrapper
{
    protected function configure()
    {
        $this
            ->setName('processSomeCommand')
            ->setDescription('Process Some Command')
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {

        if ($this->start($this->getName()) === false) {
            return 0;
        } 

        sleep(60);

        $this->stop();

    }

所有命令都由 cron 触发,在这种情况下每秒触发一次。

【问题讨论】:

  • 您确定您的生产系统与 PHP Semaphore 兼容吗? php.net/manual/en/book.sem.php
  • 是的,但是当我将其更改为 FlockStore 时,它​​工作得非常好: $store = new FlockStore(sys_get_temp_dir()); $factory = 新工厂($store);
  • 嗯..这没有意义:D

标签: php symfony locking symfony-3.4 symfony-lock


【解决方案1】:

可能与 systemd RemoveIPC 参数有关:

删除IPC= 控制 System V 和 POSIX IPC 对象是否属于 当用户完全注销时,用户将被删除。需要一个 布尔参数。如果启用,用户可能不会使用 IPC 最后一个用户会话终止后的资源。这 涵盖 System V 信号量、共享内存和消息队列,如 以及 POSIX 共享内存和消息队列。请注意,IPC root 用户和其他系统用户的对象被排除在外 这个设置的效果。默认为“是”。

如果您使用的是 systemd,那么每次 cron 结束时,用户都会注销,并且 systemd 会删除信号量。

  • 第一个 Cron 获取锁
  • 第二个 Cron 获取锁失败,用户注销,信号灯被移除
  • Thris Cron 获得锁/First Cron 不再拥有它。

正如in this thread 所讨论的那样,要么在服务器上禁用 RemoveIPC,要么使用系统用户来避免这种情况。或者正如您在评论中所说:使用另一个商店。

很可能,您应该收到警告:

PHP 警告:sem_remove():SysV 信号量 14071[redacted]0096 不(不再)存在于 [redacted]/app/vendor/symfony/lock/Store/SemaphoreStore.php 第 95 行

其他人遇到了这个问题:in this thread,他们很可能应该将其添加到文档中。

【讨论】:

    猜你喜欢
    • 2018-05-26
    • 2020-07-31
    • 1970-01-01
    • 2021-08-01
    • 1970-01-01
    • 2014-08-17
    • 2017-04-15
    • 1970-01-01
    • 2011-05-13
    相关资源
    最近更新 更多