Gearman + PHP 实现分布式对象调用

http://netkiller.github.io/journal/gearman.php.html

Mr. Neo Chen (陈景峯), netkiller, BG7NYT


中国广东省深圳市龙华新区民治街道溪山美地
518131
+86 13113668890


$Id: 9c398ce66f66eef0683cd940da22340dbed1c671

版权声明

转载请与作者联系,转载时请务必标明文章原始出处和作者信息及本声明。

文档出处:
http://netkiller.github.io
http://netkiller.sourceforge.net

微信扫描二维码进入 Netkiller 微信订阅号

QQ群:128659835 请注明“读者”

2017-06-16

摘要

在群里看到有网友问,IDC的服务器是否需要开启防火墙,我意识到应该写一篇关于IDC安全的文章。


目录

1. Gearman Job Server

文本格式回复

yum install gearmand
		

2. Gearman PHP扩展

PHP扩展安装

		
#!/bin/bash

yum install libgearman-devel -y
pecl install gearman

cat >> /srv/php/etc/conf.d/gearman.ini <<EOF
extension=gearman.so
EOF
		
		

确认模块是否安装,同时检查gearman扩展的版本。

# php -m | grep gearman
gearman

# php -r 'printf("%s\r\n",gearman_version());'
1.1.8
		

测试脚本 server.php

		
<?php
$worker= new GearmanWorker();
$worker->addServer();
$worker->addFunction("reverse", "my_reverse_function");
while ($worker->work());

function my_reverse_function($job)
{
  return strrev($job->workload());
}
?>		
		
		

测试脚本 client.php

		
<?php
$client= new GearmanClient();
$client->addServer();
print $client->doNormal("reverse", "Hello World!");
?>
		
		

我用'o' 表示与上次备份中有差异的部分。

3. 参数传递与返回值

Gearman 向functon 传递参数只能通过$job->workload(), 而 $job->workload() 只能传递字符串。

如果托传递多个参数,需要将参数序列化后传递

返回值也一样,一个字符串可以直接返回,如果返回数字类型是不允许的,需要序列化处理

例 1. 多参数传递与返回值实例

Server

			
<?php
require 'Doctrine/Common/ClassLoader.php';

use Doctrine\Common\ClassLoader;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Configuration;

$classLoader = new ClassLoader('Doctrine', '/www/DoctrineDBAL-2.3.4/');
$classLoader->register();

$config = new Configuration();

$connectionParams = array(
    'dbname' => 'example',
    'user' => 'www',
    'password' => 'password',
    'host' => '192.168.2.1',
    'driver' => 'pdo_mysql',
);
$conn = DriverManager::getConnection($connectionParams, $config);

$host = '127.0.0.1';
$port = 4730;

echo "Starting\n";

# Create our worker object.
$gmworker= new GearmanWorker();

# Add default server (localhost).
$gmworker->addServer($host, $port);

# Register function "reverse" with the server. Change the worker function to
# "reverse_fn_fast" for a faster worker with no output.
$gmworker->addFunction("members", "members");

print "Waiting for job...\n";
while($gmworker->work())
{
  if ($gmworker->returnCode() != GEARMAN_SUCCESS)
  {
    echo "return_code: " . $gmworker->returnCode() . "\n";
    break;
  }
}

function members($job)
{
	global  $conn;
	$param = unserialize($job->workload());
	print_r($param);
	$sql = "SELECT username FROM members limit ".$param['limit'].",".$param['offset'];
	$stmt = $conn->query($sql);

	while ($row = $stmt->fetch()) {
		//printf("%s\r\n", );
		$result[] = $row['username'];
	}
	return serialize($result);
}
			
			

Client

			
<?php

# create our client object
$gmclient= new GearmanClient();

# add the default server (localhost)
$gmclient->addServer();

# run reverse client in the background
$job_handle = $gmclient->doNormal("members",serialize(array('limit'=>5,'offset'=>10)));

if ($gmclient->returnCode() == GEARMAN_SUCCESS)
{
	print_r(unserialize($job_handle));
}		
				
			

运行结果

$ php client.php 
Array
(
    [0] => 257000005
    [1] => 257000006
    [2] => 257000009
    [3] => 257000010
    [4] => 257000011
    [5] => 257000012
    [6] => 257000013
    [7] => 257000014
    [8] => 257000015
    [9] => 257000016
)