我在 php 中实现了一个“管理员”钩子(Hook)到我的齿轮工作人员中。这是为了监控 worker 的整体统计数据,而不是工作。它还将提供一种允许工作人员取消注册、清理和终止的方法。我通过注册第二个函数来处理这些“管理员”请求来做到这一点。我想我可以发送一个“高”优先级的作业,而那个高优先级的作业应该抢占正常的优先级作业。情况似乎并非如此。
这是我正在运行的测试的简化版本:
worker :
<?php
$gmw = new GearmanWorker();
$gmw->addServer();
$gmw->addFunction('Test', 'handleWork');
$gmw->addFunction('Admin', 'handleAdmin');
$gmw->setTimeout(10000); // 10s wait timeout for I/O activity
$pass_count = 0;
$job_count = 0;
$kill = false;
while (@$gmw->work() || $gmw->returnCode() == GEARMAN_TIMEOUT) {
$pass_count++;
if ($kill) {
if ($gmw->returnCode() != GEARMAN_TIMEOUT) $gmw->unregisterAll();
if ($gmw->returnCode() == GEARMAN_SUCCESS) $job_count++;
print("\n\nKill command received, exiting...");
stats(false);
break;
}
if ($gmw->returnCode() == GEARMAN_TIMEOUT) {
continue;
} else if ($gmw->returnCode() != GEARMAN_SUCCESS) {
$gmw->unregisterAll();
print("\n\nGot Gearman Code \"" . $gmw->returnCode() . "\", exiting");
break;
}
$job_count++;
}
function handleWork(GearmanJob $job) {
print('.');
usleep(100000);
return '{"consumed": true}';
}
function handleAdmin(GearmanJob $job) {
global $kill, $pass_count, $job_count;
$payload = json_decode($job->workload());
if ($pass_count) $pass_count--;
if ($job_count) $job_count--;
switch ($payload->action) {
case 'kill':
$kill = true;
return json_encode(array(
'message' => 'Kill request received',
));
case 'stats':
return json_encode(stats(true));
}
}
function stats($return=true) {
global $pass_count, $job_count;
$obj = array(
'pass_count' => $pass_count,
'job_count' => $job_count,
);
if ($return) return $obj;
foreach ($obj as $k => $v) {
print("\n" . $k . ":\t" . $v);
}
print("\n");
}
CLIENT 1(向 worker 发送正常工作)
<?php
$gmc = new GearmanClient();
$gmc->addServer();
while (true) {
print('.');
for ($i=0; $i<100; $i++) {
$gmc->addTaskBackground('Test', '{"foo":"bar"}');
}
$gmc->runTasks();
sleep(15);
}
CLIENT 2(发送请求以获取统计信息)
<?php
$gmc = new GearmanClient();
$gmc->addServer();
$gmc->setCompleteCallback('output');
$gmc->addTaskHigh('Admin', '{"action":"stats"}');
$gmc->runTasks();
function output(GearmanTask $task) {
foreach (json_decode($task->data()) as $k => $v) {
print("\n$k:\t$v");
}
print("\n");
}
CLIENT 3(发送请求杀死 worker )
<?php
$gmc = new GearmanClient();
$gmc->addServer();
$gmc->setCompleteCallback('output');
$gmc->addTaskHigh('Admin', '{"action":"kill"}');
$gmc->runTasks();
function output(GearmanTask $task) {
foreach (json_decode($task->data()) as $k => $v) {
print("\n$k:\t$v");
}
print("\n");
}
我要解决这个问题了吗?有一个更好的方法吗?请注意,运行 WORKER 和 CLIENT 1 是一个无限循环。当我运行 CLIENT 2 或 CLIENT 3 时,它总是等到 CLIENT 1 发送的前 100 个作业完成后再运行提交的作业。
最佳答案
4年后你可能对此不再感兴趣,但我还是会添加一个答案,因为答案很有趣。
Gearmand 仅按每个函数的优先级排序作业的执行。
有两种方法可以解决此限制:
另见 https://github.com/gearman/gearmand/issues/173
关于php - 高优先级齿轮工作业未被视为高优先级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21468012/