2

我从这个问题开始: Gearman:客户端请求和工作人员接收之间的 3 秒。这是正常的吗?

环境:

  • Ubuntu 12.04 桌面
  • PHP 5.3.10
  • Gearman(带有 PHP 扩展 1.1.1 的 libgearman 1.1.5)
  • 局域网上的多台服务器

我无法获得少于 3 秒的工作人员响应时间,我不知道为什么。我将其缩小到我构建的包装类。然后,我将其进一步缩小到类中的特定方法。长话短说,真正的问题似乎在于 PHP 扩展中 GearmanWorker 的 addServer 方法。

我的包装类试图连接到 3 个 Gearman 作业服务器。实际上只有 2 个正在运行。当我尝试连接到所有 3 个时,我收到关于第 3 个无法连接的警告。我还得到了 3 秒的工作人员响应时间。当我删除添加服务器的尝试时,当前关闭的作业服务器然后瞧,工作人员响应时间约为 0.003 秒。

现在您可能会问,为什么不直接从要连接的服务器列表中删除关闭的服务器?好吧,首先它不会总是失败。其次,当当前启动或 5 分钟前启动的服务器之一不再运行时会发生什么?Wham 所有作业现在至少需要 3 秒。现在我认为可能有一种方法可以将超时配置为 1 秒,但更好的解决方案 IMO 是有一种方法可以从工作人员试图从中获取工作的服务器列表中删除死服务器。

在我的研究中有一个 addServer 方法。还有一个 addFunction 方法。然后有一个取消注册方法可以从给定工作人员的列表中删除工作人员功能。但是,我看不到 removeServer 方法。

那么,有没有办法在 GearmanWorker 中剔除作业服务器列表,或者我是否需要杀死对象,重新实例化它,然后重新连接到新的、剔除的可用作业服务器列表?杀死并重新启动 GearmanWorker 似乎远非理想。

什么是扫描(并连接到)所有活动作业服务器的最佳方法,同时避免已死的作业服务器固有的超时?

谢谢

4

1 回答 1

1

所以最终看来,我并不是唯一一个遇到这个问题的人。谷歌的 Gearman 小组也没有人能指出解决方案。所以最终我编写了自己的代码(从 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 作业服务器将停止使用,并且脚本虽然可能会在短时间内变慢,但通常运行得非常快。

希望这可以帮助那里的人。

于 2013-10-31T23:28:20.770 回答