登录 |

Redis实现多机命令执行

2013年10月23日 下午 30:26 | 作者:

Agent.php

pcntl_signal(SIGCHLD, SIG_IGN);

require 'iRedis.php';

$hostname = trim(`hostname`);
$redis = new iRedis('127.0.0.1');
$redis->conn || die;

$redis2 = new iRedis('127.0.0.1');
$redis2->conn || die;

$client_list = $redis->client('setname', $hostname);
$redis->subscribe('cmd');
while ( !feof($redis->conn) ) {
        $argv = $redis->read_reply($redis->conn);
        if ( $argv === null ) {
                echo "timeout\n";
                if ( $redis->ping() ) {
                        continue;
                } else {
                        exit;
                }
        } else {
                $pid = pcntl_fork();
                if ($pid == -1) {
                        die('could not fork');
                } else if ($pid) {
                } else {
                        echo "exec\n";
                        $handle = popen($argv[2], "r");
                        while ( !feof($handle) ) {
                                if ( $response = fread($handle, 8192) ) {
                                        $redis2->publish("resp:$hostname", $response);
                                }
                        }
                        exit;
                }
        }
}

Console.php

require 'iRedis.php';
$redis = new iRedis('127.0.0.1');
$redis2 = new iRedis('127.0.0.1');

if ( empty($argv[1]) ) die("no command!\n");

$cmd = $argv[1];
if ( isset($argv[2]) ) parse_str($argv[2], $opt);

if ( !isset($opt['line']) ) $opt['line'] = "\n";

$redis->psubscribe('resp*');
$redis2->publish('cmd', $cmd." 2>&1");

$last_host = $host = '';
$hosts = array();
while ( !feof($redis->conn) ) {
        $argv = $redis->read_reply($redis->conn);
        $host = substr($argv[2],5);
        if( !array_key_exists($host, $hosts) ) $hosts[$host] = count($hosts)+1;
        if ( $argv !== null ) {
                if ( $last_host !== $host ) echo "\n\33[1;41m",str_pad($hosts[$host],3,'0',STR_PAD_LEFT)," ",$host,"\33[0m",$opt['line'];
                echo trim($argv[3]);
        }
        $last_host = $host;
}

iRedis.php

class iRedis {
        var $host;
        var $pass;
        var $port;
        var $flags;
        var $conn;

        function __construct($host=null, $port=6379) {
                if ( !empty($host) ) {
                        $this->connect($host, $port);
                }
        }

        function pconnect($host, $port=6379) {
                return $this->connect($host, $port, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT);
        }

        function connect($host, $port=6379, $flags=STREAM_CLIENT_CONNECT) {
                $this->host  = $host;
                $this->port  = $port;
                $this->flags = $flags;

                $this->conn  = stream_socket_client("tcp://$host:$port", $errno, $errstr, 10, $flags);
                if (!$this->conn) {
                        echo "$errstr ($errno)
\n"; return false; } if ( !empty($this->pass) ) { $this->auth($pass); } return $this->conn; } function auth($pass) { $this->pass = $pass; return $this->__call('auth', array($pass)); } function reconnect() { if ( $this->connect($this->host, $this->port, $this->flags) ) { if ( !empty($this->pass) ) { return $this->auth($this->pass); } return true; } return false; } function close() { fclose($this->conn); } function do_cmd($cmd) { if ( fwrite($this->conn, $cmd) === false ) { if ( !$this->reconnect() ) { return false; } return $this->do_cmd($cmd); } return $this->read_reply($this->conn); } function __call($name, $args) { array_unshift($args, $name); $argc = count($args); $cmd = '*'.$argc."\r\n"; foreach ( $args as $arg ) { $cmd .= '$'.strlen($arg)."\r\n".$arg."\r\n"; } return $this->do_cmd($cmd); } function read_reply($fd) { $argc = 1; $argv = array(); while ( $line = fgets($fd) ) { $val = substr($line,1,-2); switch ($line{0}) { case '+': case '-': case ':': $argv[] = $val; break; case '*': $argc = $val; continue 2; case '$': $len = $val; if ( $len > 0 ) { $buffer = ''; while ( $len > 0 && $chunk = fread($fd, $len) ) { $buffer .= $chunk; $len -= strlen($chunk); } $argv[] = $buffer; fread($fd,2); // -- ignore CRLF } else { $argv[] = null; } break; } if ( count($argv) == $argc ) { return $argc > 1 ? $argv : $argv[0]; } } } }

评论(5条评论)

  1. leading nba mt coins xbox one seller…

    I do not know what you are saying…

  2. u4fifa…

    Why don’t we give this a try?…

  3. FIFA 17 Comfort Trade…

    What if I had the guts to quit my job….

  4. UPAlbion.com…

    Why don’t we give this a try?…

  5. buy cheap NBA 2K17 MT PS4

    The youre very professional .

发表评论

您必须登陆才可以发表评论