我从这个问题开始: Gearman: 3 seconds between client request and worker receive. Is this normal?
环境:
我无法让工作人员的响应时间少于3秒,我无法弄清楚原因。我把它缩小到我建造的包装类。然后我将其进一步缩小到类中的特定方法。简而言之,真正的问题似乎在于PHP扩展中GearmanWorker的addServer方法。
我的包装器类试图连接到3个Gearman作业服务器。实际上只有2个正在运行。当我尝试连接所有3个时,我收到一个关于第3个无法连接的警告。我的工作人员响应时间为3秒。当我删除addServer当前向下作业服务器的尝试时,工作人员的响应时间大约是0.003秒。
现在您可能会问,为什么不从连接的服务器列表中删除服务器?好吧,首先它不会永远失败。其次,当一个当前正在运行或在5分钟前启动的服务器不再存在时会发生什么?所有工作现在至少需要3秒钟。现在我认为可能有一种方法可以将超时配置为1秒,但更好的解决方案,IMO,是为了有一种方法从工作者试图从中获取作业的服务器列表中删除死服务器。 / p>
在我的研究中,有一个addServer方法。并且有一个addFunction方法。然后有一个取消注册方法,用于从给定worker的列表中删除worker功能。但是,我没有看到removeServer方法。
那么,有没有办法剔除GearmanWorker中的作业服务器列表,还是我需要杀死该对象,重新实例化它,并重新连接到新的,剔除的可用作业服务器列表?杀死并重新启动GearmanWorker似乎远非理想。
扫描(并连接到)所有活动作业服务器的最佳方法是什么,同时避免已经死亡的作业服务器固有的超时?
由于
答案 0 :(得分:1)
所以最终我似乎并不是唯一一个有这个问题的人。 Gearman的Google群组中没有人可以指向解决方案。所以最终我编写了自己的代码(从Gearman Monitor获取部分)来确定哪些作业服务器已启动并运行,哪些不是。
try {
$cxn = @fsockopen($ip, $gHosts->ports[$host], $errCode, $errMsg, $timeout);
/* Using the new \Net_Gearman_Manager on a dead job server kept leading to
* fatal error which was uncaught. Thus crashing the script and leading
* no update of the server status
*/
//$gearmanManager = new \Net_Gearman_Manager($ip . ':' . $gHosts->ports[$host], 1);
if ($cxn === FALSE) {
write_log($fLog, 'Connection FAILED');
$output[$host] = FAILURE;
} else {
write_log($fLog, 'Connection Succeeded');
$output[$host] = SUCCESS;
}
} catch (Net_Gearman_Exception $e) {
write_log($fLog, $e->getMessage());
$output[$host] = FAILURE;
} catch (Exception $e) {
write_log($fLog, $e->getMessage());
$output[$host] = FAILURE;
} // if (@$wrkr->addServer($ip, $gHosts->ports[$host]))
$ gHosts类是一个配置类,它包含每个潜在Gearman作业服务器的IP和端口。我在$ gHosts中遍历每个潜在的作业服务器并进行测试。
然后我将输出写入memcache和文本文件。单独的memcache工作正常,直到我开始真正尝试加载机器。然后memcache连接将重复失败。现在我使用文本文件作为备份,问题已经消失。
我将最后一次连接到每个Gearman作业服务器的尝试存储在一个数组中,其中键是服务器的名称,值是上次尝试的时间戳。如果尝试成功,则时间戳为正。如果尝试失败,则时间戳为负。时间戳允许我确定数据是陈旧还是新鲜。
然后在使用Gearman的脚本中,我有一个围绕PHP扩展类的Client和Worker包装类。他们处理我想要的时间框架上的连接更新。这样停止响应的Gearman作业服务器停止使用,脚本虽然可能在一段时间内很慢,但通常运行得非常快。
希望这可以帮助那些人。