giudicelli/distributed-architecture

PHP 分布式架构

此包的官方仓库似乎已不存在,因此该包已被冻结。

0.8.5 2020-07-03 10:56 UTC

This package is auto-updated.

Last update: 2022-03-01 00:35:39 UTC


README

PHP 分布式架构是一个旨在帮助管理分布式架构的库。它的唯一目的是在本地或远程服务器上启动进程。

安装

$ composer require giudicelli/distributed-architecture

使用

要运行您的分布式架构,您主要需要使用两个类 Master\Launcher 和 Slave\Handler。

主进程

以下是一个启动主进程的简单示例。

"Launcher::run" 方法将在每个组中的每个从属进程退出后返回。

use giudicelli\DistributedArchitecture\Master\Handlers\GroupConfig;
use giudicelli\DistributedArchitecture\Master\Handlers\Local\Config as LocalConfig;
use giudicelli\DistributedArchitecture\Master\Handlers\Remote\Config as RemoteConfig;
use giudicelli\DistributedArchitecture\Master\Launcher;
use Psr\Log\AbstractLogger;

class Logger extends AbstractLogger
{
    public function log($level, $message, array $context = [])
    {
        foreach ($context as $key => $value) {
            $message = str_replace('{'.$key.'}', $value, $message);
        }
        echo "{$level} - {$message}\n";
        flush();
    }
}

$logger = new Logger();

$groupConfigs = [
    (new GroupConfig())
        ->setName('First Group')
        ->setCommand('script1.php')
        ->setParams(['message' => 'Hello World!'])
        ->setProcessConfigs([
            (new LocalConfig())
                ->setInstancesCount(3),
            (new RemoteConfig())
                ->setHosts(['remote-server-1', 'remote-server-2'])
                ->setInstancesCount(2),
        ]),
    (new GroupConfig())
        ->setName('Second Group')
        ->setCommand('script2.php')
        ->setProcessConfigs([
            (new LocalConfig())
                ->setInstancesCount(2),
            (new RemoteConfig())
                ->setHosts(['remote-server-1', 'remote-server-2'])
                ->setInstancesCount(2),
        ]),
];
$master = new Launcher($logger);
$master->run($groupConfigs);

上述代码创建了两个组。

一个组被称为“第一组”,它将在本地机器上运行 "script1.php",

  • 3 个实例,
  • 2 个实例在 "remote-server1" 机器上,
  • 2 个实例在 "remote-server2" 机器上。

总共将运行 7 个 "script1.php" 实例。

另一个组被称为“第二组”,它将在本地机器上运行 "script2.php",

  • 2 个实例,
  • 2 个实例在 "remote-server1" 机器上,
  • 2 个实例在 "remote-server2" 机器上。

总共将运行 6 个 "script2.php" 实例。

从属进程

从属进程必须使用 "Slave\Handler" 类,因为主进程可能会发送需要处理的命令。它还允许您的脚本在主进程请求时干净地退出。使用上述示例,以下是对 "script1.php" 或 "script2.php" 的实现示例。

use giudicelli\DistributedArchitecture\Slave\Handler;
use giudicelli\DistributedArchitecture\Slave\HandlerInterface;
use Psr\Log\LoggerInterface;

if (empty($_SERVER['argv'][1])) {
    echo "Empty params\n";
    die(1);
}

$handler = new Handler($_SERVER['argv'][1]);
$handler->run(function (HandlerInterface $handler) {
    $groupConfig = $handler->getGroupConfig();

    $params = $groupConfig->getParams();

    // Anything echoed here will be considered log level "info" by the master process.
    // If you want another level for certain messages, use $handler->getLogger().
    // echo "Hello world!\n" is the same as $handler->getLogger()->info('Hello world!')

    echo "My ID : ".$handler->getId()."\n";
    echo "My Group ID : ".$handler->getGroupId()."\n";
    echo "There are a total of ".$handler->getGroupCount()." processes in my group named \"".$groupConfig->getName()."\"\n";
    echo $params['message']."\n";

    while(!$handler->mustStop()) {
        // Do a very long task
        // ...

        // Let master know we're still running
        $handler->ping();
    }
});

示意图

以下是解释其工作原理的基本示意图。