【问题标题】:Beanstalkd (via pheanstalk) allowing duplicate, simultaneous reserves?Beanstalkd(通过 pheanstalk)允许重复的同时保留?
【发布时间】:2013-03-06 07:39:03
【问题描述】:

试图将 Pheanstalk 包装在我的 PHP 作业基类中。我正在测试具有延迟功能的保留和保留,我发现我可以从我的基类的第二个实例中保留一个作业,而无需第一个实例释放作业或 TTR 超时。这是出乎意料的,因为我认为这正是作业队列应该防止的事情。这是第一个 put 和第一个保留的 beanstalkd 命令以及时间戳。最后我还做了一个 stats-job 请求:

01:40:15: Sending command: use QueuedCoreEvent
01:40:15: Got response: USING QueuedCoreEvent

01:40:15: Sending command: put 1024 0 300 233
a:4:{s:9:"eventName";s:21:"ReQueueJob_eawu7xr9bi";s:6:"params";a:2:{s:12:"InstanceName";s:21:"ReQueueJob_eawu7xr9bi";s:17:"aValueToIncrement";i:123456;}s:9:"behaviors";a:1:{i:0;s:22:"BehMCoreEventTestDummy";}s:12:"failureCount";i:0;}
01:40:15: Got response: INSERTED 10

01:40:15: Sending command: watch QueuedCoreEvent
01:40:15: Got response: WATCHING 2

01:40:15: Sending command: ignore default
01:40:15: Got response: WATCHING 1

01:40:15: Sending command: reserve-with-timeout 0
01:40:15: Got response: RESERVED 10 233
01:40:15: Data: a:4:{s:9:"eventName";s:21:"ReQueueJob_eawu7xr9bi";s:6:"params";a:2:{s:12:"InstanceName";s:21:"ReQueueJob_eawu7xr9bi";s:17:"aValueToIncrement";i:123456;}s:9:"behaviors";a:1:{i:0;s:22:"BehMCoreEventTestDummy";}s:12:"failureCount";i:0;}

01:40:15: Sending command: stats-job 10
01:40:15: Got response: OK 162
01:40:15: Data: ---
id: 10
tube: QueuedCoreEvent
state: reserved
pri: 1024
age: 0
delay: 0
ttr: 300
time-left: 299
file: 0
reserves: 1
timeouts: 0
releases: 0
buries: 0
kicks: 0

到目前为止,一切都很好。现在我从我的基类的第二个实例做另一个储备,然后是另一个统计作业请求。请注意,时间戳在同一秒内,与我设置的 300 秒 TTR 相去甚远。另请注意,在第二个 stats-job 打印输出中,该作业有 2 个保留,其中 0 个超时和 0 个释放。

01:40:15: Sending command: watch QueuedCoreEvent
01:40:15: Got response: WATCHING 2

01:40:15: Sending command: ignore default
01:40:15: Got response: WATCHING 1

01:40:15: Sending command: reserve-with-timeout 0
01:40:15: Got response: RESERVED 10 233
01:40:15: Data: a:4:{s:9:"eventName";s:21:"ReQueueJob_eawu7xr9bi";s:6:"params";a:2:{s:12:"InstanceName";s:21:"ReQueueJob_eawu7xr9bi";s:17:"aValueToIncrement";i:123456;}s:9:"behaviors";a:1:{i:0;s:22:"BehMCoreEventTestDummy";}s:12:"failureCount";i:0;}

01:40:15: Sending command: stats-job 10
01:40:15: Got response: OK 162
01:40:15: Data: ---
id: 10
tube: QueuedCoreEvent
state: reserved
pri: 1024
age: 0
delay: 0
ttr: 300
time-left: 299
file: 0
reserves: 2
timeouts: 0
releases: 0
buries: 0
kicks: 0

有人对我可能做错了什么有任何想法吗?我需要做些什么来告诉队列我希望一次只能由一名工作人员访问作业吗?一旦我将工作从队列中取出,我就会在 pheanstalk 实例上进行“取消设置”,我相信这会终止与 beanstalkd 的会话。这是否会导致 beanstalkd 决定工人已经死亡并自动释放工作而没有超时?我不确定 beanstalkd 有多少依赖会话状态来确定工作状态。我假设我可以不受惩罚地打开和关闭会话,并且工作 ID 是 beanstalkd 唯一关心的将工作操作联系在一起的东西,但这对我来说可能是愚蠢的......这是我第一次涉足工作队列.

谢谢!

【问题讨论】:

  • 我不知道问题是什么,但我在尝试确定为什么我的 pheanstalk->reserve() 调用停止时发现它 - 即永远不会返回 - 导致我的 cron 作业无限期运行,直到 Apache 有效死亡。但是我要说的是,一旦工作完成,您可能会想要删除它。否则,只要您有工作人员运行队列作业,它将保留在队列中,然后每 300 次(最佳情况)再次运行。至于通信 btwn pheanstalk 实例未设置和发布工作,我无法发表评论。

标签: php queue beanstalkd pheanstalk


【解决方案1】:

我的猜测是您的第一个客户端实例在第二个客户端实例保留作业之前关闭了到 beanstalkd 服务器的 TCP 套接字。

关闭 TCP 连接会隐式将作业释放回队列中。这些隐式释放(关闭连接、quit 命令等)似乎不会增加releases 计数器。

这是一个例子:

# Create a job, reserve it, close the connection:
pda@paulbookpro ~ > telnet 0 11300
Trying 0.0.0.0...
Connected to 0.
Escape character is '^]'.
put 0 0 600 5
hello
INSERTED 1
reserve
RESERVED 1 5
hello
^]
telnet> close
Connection closed.

# Reserve the job, stats-job shows two reserves, zero releases.
# Use 'quit' command to close connection.
pda@paulbookpro ~ > telnet 0 11300
Trying 0.0.0.0...
Connected to 0.
Escape character is '^]'.
reserve
RESERVED 1 5
hello
stats-job 1
OK 151
---
id: 1
tube: default
state: reserved
pri: 0
age: 33
delay: 0
ttr: 600
time-left: 593
file: 0
reserves: 2
timeouts: 0
releases: 0
buries: 0
kicks: 0

quit
Connection closed by foreign host.

# Reserve the job, stats-job still shows zero releases.
# Explicitly release the job, stats-job shows one release.
pda@paulbookpro ~ > telnet 0 11300
Trying 0.0.0.0...
Connected to 0.
Escape character is '^]'.
reserve
RESERVED 1 5
hello
stats-job 1
OK 151
---
id: 1
tube: default
state: reserved
pri: 0
age: 46
delay: 0
ttr: 600
time-left: 597
file: 0
reserves: 3
timeouts: 0
releases: 0
buries: 0
kicks: 0

release 1 0 0
RELEASED
stats-job 1
OK 146
---
id: 1
tube: default
state: ready
pri: 0
age: 68
delay: 0
ttr: 600
time-left: 0
file: 0
reserves: 3
timeouts: 0
releases: 1
buries: 0
kicks: 0

quit
Connection closed by foreign host.

【讨论】:

    【解决方案2】:

    我遇到了同样的问题。问题出在对 beanstalkd 的多个连接中。

    use Pheanstalk\Pheanstalk;
    
    $pheanstalk = connect();
    $pheanstalk->put(serialize([1]), 1, 0, 1800);
    
    /** @var Job $job */
    $job = $pheanstalk->reserve(10);
    print_r($pheanstalk->statsJob($job->getId()));
    // state reserved but
    // only those connection that reserved a job can resolve/update it
    
    $pheanstalk2 = connect();
    print_r($pheanstalk->statsJob($job->getId()));
    $pheanstalk2->delete($job);
    // new connection opened in same process still cannot update the job 
    
    // PHP Fatal error:  Uncaught Pheanstalk\Exception\ServerException: Cannot delete job 89: NOT_FOUND in /var/www/vendor/pda/pheanstalk/src/Command/DeleteCommand.php:45
    
    
    function connect() {
        $pheanstalk = new Pheanstalk(
            'localhost',
            11300,
            5
        );
        return $pheanstalk;
    }
    

    【讨论】:

      猜你喜欢
      • 2017-07-14
      • 1970-01-01
      • 2013-07-31
      • 2016-09-21
      • 2021-01-22
      • 2017-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多