标题党强势注入。
Yar 是一个轻量级, 高效的 RPC 框架, 它提供了一种简单方法来让 PHP 项目之间可以互相远程调用对方的本地方法. 并且 Yar 也提供了并行调用的能力. 可以支持同时调用多个远程服务的方法.
Yar 鸟哥博客介绍 http://www.laruence.com/2012/09/15/2779.html
Yar 鸟哥原始项目 https://github.com/laruence/yar
Yar Java Client 则实现了跨语言的远程调用。使得 Java 客户端能够调用 Yar PHP 服务器端本地的方法。
Github: https://github.com/zhoumengkang/yar-java-client
两个 rpc api ,模拟的业务场景是点赞赠送金币和发布帖子赠送金币。
<?php
class RewardScoreService {
/**
* $uid 给 $fid 点赞
* @param $fid interge
* @param $uid interge
* @return void
*/
public function support($uid,$fid){
return "support:uid:$uid:fid:$fid";
}
/**
* $uid 发布了帖子 $fid
* @param $fid interge
* @param $uid interge
* @return void
*/
public function post($uid,$fid){
return "post:uid:$uid:fid:$fid";
}
}
$yar_server = new Yar_server(new RewardScoreService());
$yar_server->handle();
public class YarClientTest extends TestCase {
/**
* 定义 rpc 接口
*/
public interface RewardScoreService{
String support(int uid,int fid);
String post(int uid,int fid);
}
/**
* rpc api 地址
*/
static String uri = "http://mengkang.net/demo/yar-server/RewardScoreService.php";
public void testUserService(){
// 第一种调用方式
YarClient yarClient = new YarClient(uri);
RewardScoreService rewardScoreService = (RewardScoreService) yarClient.useService(RewardScoreService.class);
for (int i = 0; i < 10; i++) {
System.out.println(rewardScoreService.support(1, 2));
}
// 第二种调用方式
YarClientOptions yarClientOptions = new YarClientOptions();
yarClientOptions.setConnect_timeout(2000);
YarClient yarClient2 = new YarClient(uri,yarClientOptions);
RewardScoreService rewardScoreService2 = (RewardScoreService) yarClient2.useService(RewardScoreService.class);
for (int i = 0; i < 10; i++) {
System.out.println(rewardScoreService2.post(1, 20));
}
}
}
考虑到 Java 和 PHP 的数据类型的不同,这里做了一个折中的处理,返回数据类型客户端框架统一以 Object 类型接受,然后使用时再根据接口定义的数据类型进行转换。
这里的方法的命令皆以 Yar 原版为准则。
YarConcurrentClient.call
方法注册,
YarConcurrentClient.loop
并行调用,
YarConcurrentClient.reset
清空任务。
回调函数需要继承实现YarConcurrentCallback
里面定义了两个方法:async
是针对并行调用发出之后立即执行的任务,而success
则是每个请求之后返回的结果。
public class YarConcurrentClientTest extends TestCase {
/**
* rpc api 地址
*/
static String uri = "http://mengkang.net/demo/yar-server/RewardScoreService.php";
public class callback extends YarConcurrentCallback {
public void async() {
System.out.println("现在, 所有的请求都发出去了, 还没有任何请求返回");
}
public Object success() {
return retValue;
}
}
public class errorCallback extends YarConcurrentErrorCallback {
@Override
void error() {
System.out.println("出错了");
}
}
public void testLoop() throws Exception {
String packagerName = YarConfig.getString("yar.packager");
YarClientOptions yarClientOptions = new YarClientOptions();
yarClientOptions.setConnect_timeout(2000);
for (int i = 0; i < 10; i++) {
// 第一种调用方式
YarConcurrentClient.call(new YarConcurrentTask(uri, "support", new Object[]{1, 2}, packagerName, new callback()));
// 第二种调用方式 增加一些额外配置选项
YarConcurrentClient.call(new YarConcurrentTask(uri, "support", new Object[]{1, 2}, packagerName, new callback(),yarClientOptions));
}
for (int i = 0; i < 10; i++) {
// 第三种调用方式 有正确的回调和错误的回调
YarConcurrentClient.call(new YarConcurrentTask(uri,"post",new Object[]{1,2},packagerName,new callback(),new errorCallback()));
// 第四种调用方式 在第三种的基础上增加额外的配置选项
YarConcurrentClient.call(new YarConcurrentTask(uri,"post",new Object[]{1,2},packagerName,new callback(),new errorCallback(),yarClientOptions));
}
YarConcurrentClient.loop(new callback());
YarConcurrentClient.reset();
}
}
1
xufang 2015-12-26 12:37:13 +08:00 1
http2 普及之后,这些 RPC 都得跪。。。
|
2
xufang 2015-12-26 12:39:11 +08:00 1
curl 的 http2 的实现还不成熟,所以一时半会 php-curl 还用不起 http2 ,这是个问题。
java 的 okhttp 库倒是很成熟的,可惜是在客户端。不过服务端有 nginx 挡在前面,也无所谓。 |
6
reeco 2015-12-26 12:43:57 +08:00 via iPhone
java 的 rpc 好像要成熟很多
|
7
xufang 2015-12-26 12:46:25 +08:00
@reeco 是在服务端组件内部通信比较完善,不过现在互联网那个的趋势是块糙猛,所以客户端倒是 java(安卓),服务端 php 这个比较常见
|
8
phoneli 2015-12-26 12:56:43 +08:00
thrift 呢?
|
9
ncisoft 2015-12-26 13:00:21 +08:00 via Android
实在没看出哪就快如闪电了,,,
|
11
xufang 2015-12-26 13:04:51 +08:00
@phoneli thift 各个语言的绑定的坑比较多。性能的话,如果基于 http2 选用 protobuf 序列化和 h2c 协议的话,没有差别。
不过 http2 用起来都是简单,外部接口一般就是 jsonrpc over http2 了。内部组件的才会用上面这种方式。 |
13
xufang 2015-12-26 13:14:11 +08:00
@phoneli 恩。封装太重,出了问题要调试一番才知道问题在哪。而 http2 最大的优势是保持了 http 语义的不便,使用起来傻瓜话,不会出现所谓的“误用”。
|
14
zonghua 2015-12-26 16:59:43 +08:00 via iPhone
微博用的是这个吗?微博可是越来越慢了。
|
15
zhoumengkang OP @xufang 说得很对。都得学习!
|
16
zhoumengkang OP @ncisoft 标题党,把拉进来看看。。不好意思哈。
|
17
mengzhuo 2015-12-27 09:09:08 +08:00 via iPhone
rpc 的性能消耗最大在于序列化
真要拼速度的话 我想没人能干的过 capno |
18
zhoumengkang OP @mengzhuo 好,谢谢,回头看看,好多高人呀!
|