常见的RPC框架
phprpc,yar, thrift, gRPC, swoole, hprose
下面重点讲一讲 yar 的安装使用 以及 在tp5中的使用
欢迎加入QQ技术交流群:604438441 腾讯课堂搜索:lampol 学习PHP技术视频教程
Yar介绍
Yar 是一个轻量级, 高效的RPC框架, 它提供了一种简单方法来让PHP项目之间可以互相远程调用对方的本地方法. 并且Yar也提供了并行调用的能力. 可以支持同时调用多个远程服务的方法.
支持多种打包协议(msgpack, json, php)
文档:
http://php.net/manual/zh/book.yar.php
作者 不用介绍了 肯定都知道 搞PHP的
yar是作为一个php扩展,所以需要编译,yar用msgpack的打包协议,所以要首先安装一下
msgpack
msgpack 介绍 以及安装
MessagePack(以下简称MsgPack)一个基于二进制高效的对象序列化类库,可用于跨语言通信。它可以像JSON那样,在许多种语言之间交换结构对象;但是它比JSON更快速也更轻巧。支持Python、Ruby、Java、C/C++等众多语言。比Google Protocol Buffers还要快4倍。
MessagePack: It's like JSON. but fast and small.
官网:
https://msgpack.org/
安装msgpack
下载
msgpack http://pecl.php.net/get/msgpack-2.0.3.tgz
编译
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make && make install
引入
extension = /usr/local/php/lib/php/extensions/no-debug-non-zts-20170718/msgpack.so
重启php
yar 安装
下载
http://pecl.php.net/get/yar-2.0.5.tgz
编译
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config --enable-msgpack
make && make install
yar.so 配置到 php.in
extension = /usr/local/php/lib/php/extensions/no-debug-non-zts-20170718/yar.so
yar简单使用 demo
server.php<?phpclass User{ public function getName(){ return 'hello yar'; }}$server =new Yar_Server(new User);$server->handle();client.php<?php $client = new Yar_Client('http://192.168.113.136/server.php');echo $client->getName();
Yar_Server
一个属性 两个方法
Yar_Server { protected $_executor ; final public __construct ( Object $obj ) public handle ( void ) : boolean }
__construct ( Object $obj )
创建一个Yar的HTTP RPC服务,参数 $obj 对象的所有公开方法都会被注册为服务函数, 可以被RPC调用。返回一个Yar_Server的实例。
handle ( void )
启动服务, 开始接受客户端的调用请求.
Yar_Client
Yar_Client { /* 属性 */ protected $_protocol ; protected $_uri ; protected $_options ; protected $_running ; /* 方法 */ public __call ( string $method , array $parameters ) : void final public __construct ( string $url ) public setOpt ( number $name , mixed $value ) : boolean}
__construct ( string $url ) // 服务端的HTTP URL路径.
__call 魔术方法 第一个参数 是调用方法 第二个参数是 传递的参数
setOpt ( number $name , mixed $value )设置调用远程服务的一些配置, 比如超时值, 打包类型等
name
可以是: YAR_OPT_PACKAGER, YAR_OPT_PERSISTENT (需要服务端支持keepalive), YAR_OPT_TIMEOUT, YAR_OPT_CONNECT_TIMEOUT
Yar_Concurrent_Client
Yar_Concurrent_Client { /* 属性 */ static $_callstack ; static $_callback ; static $_error_callback ; /* 方法 */ public static call ( string $uri , string $method , array $parameters [, callable $callback ] ) : int public static loop ([ callable $callback [, callable $error_callback ]] ) : boolean public static reset ( void ) : bool }
Yar_Concurrent_Client::call ( string $uri , string $method , array $parameters [, callable $callback ] )
注册一个并行的(异步的)远程服务调用, 不过这个调用请求不会被立即发出, 而是会在接下来调用 Yar_Concurrent_Client::loop()的时候才真正的发送出去.
uri
RPC 服务的 URI(http 或 tcp).
method
调用的服务名字(也就是服务方法名).
parameters 数组
调用的参数.
callback 可选 //不设置 可以在 loop设置
回调函数, 在远程服务的返回到达的时候被Yar调用, 从而可以处理返回内容.
function callback($retRes,$callifo){
}
第一个参数 是返回的数据 第二个参数是请求的信息
Yar_Concurrent_Client::loop ([ callable $callback [, callable $error_callback ]] )
发送所有的已经通过 Yar_Concurrent_Client::call()注册的并行调用, 并且等待返回.
所有请求发送成功调用一次callback 此时参数值为 null
发送成功后 获取结果 也会调用一次callback
Yar_Concurrent_Client::reset ( void )
在一个程序中分两次并发,在第二次的返回结果中会包含第一次并发请求的返回结果,使用此方法 清除第一次
清除所有注册的回调
Yar_Server_Exception 服务端异常
Yar_client_Exception 客户端异常
yar配置
yar.packager
设置Yar的打包工具, 可以是PHP(serialize), JSON, Msgpack(这个需要编译的时候指定--enable-msgpack).
yar.debug
打开的时候, Yar会把请求过程的日志都打印出来(到stderr).
yar.connect_timeout
连接超时(毫秒为单位)
yar.timeout
处理超时(毫秒为单位)
yar.expose_info
如果关闭, 则当通过浏览器访问Server的时候, 不会出现Server Info信息.
thinkphp使用yar
thinkphp5.0版本
Server.phpnamespace appindexcontroller;use thinkcontrollerYar;class Server extends Yar{ public function index(){ return 'hello yar'; } public function test($age=null){ //传参数 要有默认值 return 'hello yar'; }}Client.phpnamespace appindexcontroller;use thinkcontrollerYar;class Client{ public function index() { $client = new Yar_Client('http://192.168.113.136:81/server'); $client->SetOpt(YAR_OPT_PACKAGER,'php'); //注意tp5只能用php msgpack以及json报错 echo $client->index(); }}
thinphp5.1 框架已经移除自己添加
添加下面 代码 然后在引入即可
abstract class Yar{ /** * 构造函数 * @access public */ public function __construct() { //控制器初始化 if (method_exists($this, '_initialize')) { $this->_initialize(); } //判断扩展是否存在 if (!extension_loaded('yar')) { throw new Exception('not support yar'); } //实例化Yar_Server $server = new Yar_Server($this); // 启动server $server->handle(); } /** * 魔术方法 有不存在的操作的时候执行 * @access public * @param string $method 方法名 * @param array $args 参数 * @return mixed */ public function __call($method, $args) {}}
常见的几个问题
1 php版本一定要 7.0以上的
2 PHP Fatal error: Yar_Client::__call(): unsupported packager msgpack
这个问题 应该是编译 yar的时候 没有 加 --enable-msgpack
3 [msgpack] (php_msgpack_unserialize) Extra bytes in xxx
这个在 tp5使用 就是 tp5 打包协议 不能用msgpack 和 json 只能选择 php (这个问题暂时还没有解决,应该是tp5框架问题)