Beanstalkd (через peanstalk), позволяющий дублировать одновременные резервы?

Попытка обернуть Pheanstalk в мой базовый класс работы PHP. Я тестирую резервирование и резервирование с функцией задержки, и я обнаружил, что могу резервировать задание из второго экземпляра моего базового класса без первого экземпляра, освобождающего задание или истечения времени TTR. Это неожиданно, так как я думал, что это именно то, что должны предотвращать очереди заданий. Вот команды beanstalkd для первого размещения и первого резерва вместе с отметками времени. Я также делаю запрос статистики в конце:

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, которые я установил. Также обратите внимание на эту вторую распечатку задания статистики, что есть 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

У кого-нибудь есть идеи о том, что я могу делать неправильно? Есть ли что-то, что я должен сделать, чтобы сообщить очереди, что я хочу, чтобы к заданиям обращался только один работник за раз? Я делаю «сброс» экземпляра peanstalk, как только получаю задание из очереди, что, как я полагаю, завершает сеанс с помощью beanstalkd. Может ли это привести к тому, что beanstalkd решит, что работник умер, и автоматически выпустит задание без тайм-аута? Я не уверен, насколько beanstalkd полагается на состояние сеанса для определения рабочего состояния. Я предполагал, что смогу открывать и закрывать сеансы безнаказанно, и что идентификатор задания был единственным, о чем beanstalkd заботился, чтобы связать операции задания вместе, но это, возможно, было глупо с моей стороны... Это мой первый набег на очереди заданий .

Спасибо!


person user2180113    schedule 18.03.2013    source источник
comment
Я понятия не имею, в чем проблема, но я нашел ее, пытаясь определить, почему мой вызов pheanstalk->reserve() останавливался, то есть никогда не возвращался, что приводило к тому, что мое задание cron выполнялось бесконечно, пока Apache фактически не умер. Однако я бы сказал, что как только работа будет завершена, вы, вероятно, захотите ее удалить. В противном случае он останется в очереди, а затем будет запускаться снова каждые 300 (в лучшем случае) до тех пор, пока у вас есть рабочие, выполняющие задания в очереди. Что касается связи между отключением экземпляра pheanstalk и выпуском задания, я не могу комментировать.   -  person Gabe Spradlin    schedule 20.03.2013


Ответы (2)


Я предполагаю, что ваш первый экземпляр клиента закрыл сокет TCP для сервера beanstalkd до того, как второй зарезервировал задание.

Закрытие соединения 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.
person Paul Annesley    schedule 01.04.2013

У меня такая же проблема. Проблема заключалась в нескольких открытых подключениях к 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;
}
person radzserg    schedule 25.10.2018