根据官方要求,需要安装msgpack 和yar的PHP扩展,扩展安装时,应注意与PHP版本的兼容问题。
作者鸟哥的网站介绍:http://www.laruence.com/2012/09/15/2779.html
PHP官网介绍:http://php.net/manual/zh/book.yar.php
github官网介绍:https://github.com/laruence/yar
msgpack(二进制数据传输,配合yar用):http://pecl.php.net/package/msgpack
yar下载地址:http://pecl.php.net/package/yar
msgpack 扩展安装
find / -name phpize # 寻找到phpize的路径/usr/local/php/bin/phpize wget http://pecl.php.net/get/msgpack-0.5.7.tgz tar -zxvf msgpack-0.5.7.tgz cd msgpack-0.5.7 /usr/local/php/bin/phpize ./configure --with-php-config=/usr/local/php/bin/php-config make && make install # 生成的文件 Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/memcache.so Installing header files: /usr/local/php/include/php/ # 在php.ini 里面添加如下内容 [msgpack] extension = msgpack.so
yar 扩展安装
find / -name phpize # 寻找到phpize的路径 /usr/local/php/bin/phpize wget http://pecl.php.net/get/yar-1.2.5.tgz tar -zxvf yar-1.2.5.tgz cd yar-1.2.5 /usr/local/php/bin/phpize ./configure --with-php-config=/usr/local/php/bin/php-config --enable-msgpack make && make install Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/yar.so # 在php.ini 里面添加如下内容 [yar] extension = yar.so
yar
原生 Server端
class API { /** * the doc info will be generated automatically into service info page. * @params * @return */ public function some_method($parameter, $option = "foo") { return $parameter; } protected function client_can_not_see() { } } $service = new Yar_Server(new API()); $service->handle();
原生 Client端
$client = new Yar_Client("http://host/api/"); // 如果有命名空间,则采用$client = new Yar_Client("http://host/api/"); /* the following setopt is optinal */ $client->SetOpt(YAR_OPT_CONNECT_TIMEOUT, 1000); /* call remote service */ $result = $client->some_method("parameter");
原生 Client端 并行调用
function callback($retval, $callinfo) { var_dump($retval); } function error_callback($type, $error, $callinfo) { error_log($error); } Yar_Concurrent_Client::call("http://xy.zhinong.com/index.php/Home/Ceshi", "some_method", array("parameters"), "callback"); Yar_Concurrent_Client::call("http://xy.zhinong.com/index.php/Home/Ceshi", "some_method", array("parameters"), "callback"); Yar_Concurrent_Client::call("http://xy.zhinong.com/index.php/Home/Ceshi", "some_method", array("parameters"), "callback"); Yar_Concurrent_Client::call("http://xy.zhinong.com/index.php/Home/Ceshi", "some_method", array("parameters"), "callback"); Yar_Concurrent_Client::loop(); //send Yar_Concurrent_Client::call("http://xy.zhinong.com/index.php/Home/Ceshi", "some_method", array("parameters"), "callback"); // if the callback is not specificed Yar_Concurrent_Client::call("http://xy.zhinong.com/index.php/Home/Ceshi", "some_method", array("parameters")); // callback in loop will be used Yar_Concurrent_Client::call("http://xy.zhinong.com/index.php/Home/Ceshi", "some_method", array("parameters"), "callback", "error_callback", array(YAR_OPT_PACKAGER => "json")); //this server accept json packager Yar_Concurrent_Client::call("http://xy.zhinong.com/index.php/Home/Ceshi", "some_method", array("parameters"), "callback", "error_callback", array(YAR_OPT_TIMEOUT=>1)); //custom timeout Yar_Concurrent_Client::loop("callback", "error_callback"); //send the requests,
这样, 所有的请求会一次发出, 只要有任何一个请求完成, 回调函数”callback”就会被立即调用.
这里还有一个细节, Yar见缝插针的不会浪费任何时间, 在这些请求发送完成以后, Yar会调用一次callback, 和普通的请求返回回调不同, 这次的调用的$callinfo参数为空.
这样一来, 我们就可以先发送请求, 然后再第一次回调, 继续做我们当前进程的工作, 等所有工作结束以后, 再交给Yar去获取并行RPC的响应.
function callback($retval, $callinfo) { if ($callinfo == NULL) { //做本地的逻辑 return TRUE; } //RPC请求返回, 返回值在$retval } 有了这些, 我们就可以把一个Web应用中, 多个数据源并行处理, 从而也能把这些逻辑解耦, 分开部署…
ThinkPHP Client端
namespace HomeController; use ThinkControllerYarController; /** * 的 * @param interge * @return interge */ class CeshiController extends YarController { /** * 第一个接口 * @param interge * @return interge */ public function some_method($parameter, $option = "foo") { // 1212 return $parameter; } protected function client_can_not_see() { } }
ThinkPHP Server端
namespace HomeController; use ThinkController; class Ceshi1Controller extends Controller { /** * 第一个接口 * @param interge * @return interge */ public function index(){ $client = new Yar_client('http://xy.zhinong.com/index.php/Home/Ceshi/index'); $result = $client->some_method(); var_dump($result); // 结果:.. } }
/************************** * 与yar后端通信 * * @param array $value 获取的post值 * @param Object $client Yar 客户端 * @write zss * @return ****************************/ public function ajaxPost() { $value = I('post.'); // Yar 客户端 $client = new Yar_client('http://zndata.'.C('TOP_DOMAIN').'/index.php/Pc'); // 获取后端的方法 $res = $client -> xy($value['method'], $value); $this->ajaxReturn($res); die; } 如果调用时间太长,设置超时,可以使用 ini_set("yar.timeout",60000);
新加入model 层接入
// $model model层,$mothod model 层的方法 ,$param_data 传入model层的方法 $url = 'http://zndata.zhinong.com/index.php/Pc'; $yar = new Yar_client($url); $res= $yar -> model_data( $model , $mothod, $param_data); // 例子 $param_data = array( 'did'=> '1', 'cid' => 'a' ); $res= $yar -> model_data( 'WikiDoc' , 'wiki', $param_data);