- 本文地址: https://www.laruence.com/2020/03/16/5578.html
- 转载请注明出处
Yar(Yet Another RPC framework)是一个轻量级支持并行调用的PHP RPC框架,是我还在微博的时候为了优化微博的性能而开发的一个工具,Yar的并行调用在微博被大量应用以降低用户请求耗时。
最近还是因为疫情,我把Yaf,Yaconf都优化了一轮,今天也完成了Yar的优化(事实上,Yar之前写的就还不错,没啥可优化的,哈哈),也新增了俩个能力。我来简单介绍下:
链接持久化
也就是YAR_OPT_PERSISTENT, 这个配置之前一直有,只不过之前是设计为跨请求的持久化,这次做了优化,变成了基于PHP请求生命期的链接保持。
也就是说,当你对一个Yar_Client设置了YAR_OPT_PERSISTEN为true的话,在一次RPC调用结束后,Yar不会销毁这个链接,从而加速后续的针对同样这个Client的RPC调用,我们来看个例子:
<?php
function bench($client) {
$start = microtime(true);
$client->header("connection");
echo microtime(true) - $start, "s\n";
}
$client = new Yar_Client("http://remote_host/index.php");
$client->setOpt(YAR_OPT_PERSISTENT, 1);
bench($client);
bench($client);
bench($client);
输出:
0.090613842010498s
0.045492887496948s
0.045512914657593s
可见,第二次调用的时候,耗时降低了一半,这是因为节省了TCP链接建立的耗时。
最后,链接会在PHP请求结束以后,整体释放,也就是PHP请求生命期的存活,不会垮请求,也不用担心内存泄漏。
不过很遗憾,这个并不能用于加速并行调用:
function callback($retval, $callinfo) {
global $start;
if ($callinfo) {
echo "Num ", $callinfo["sequence"] , " costs: ", microtime(true) - $start, "s\n";
}
}
Yar_Concurrent_Client::call("http://remote_host/index.php", "header", array("connection"), NULL, NULL, array(YAR_OPT_PERSISTENT=>1));
$start = microtime(true);
Yar_Concurrent_Client::loop("callback", function($error) { var_dump($error); });
$start = microtime(true);
Yar_Concurrent_Client::loop("callback", function($error) { var_dump($error); });
我们会发现俩次调用没有加速的效果:
Num 1 costs: 0.091023921966553s
Num 1 costs: 0.090677976608276s
这跟Yar底层使用的libcurl有关系,从libcurl的官方文档关于curl_multi_add_handle:
When an easy interface is added to a multi handle, it will use a shared connection cache owned by the multi handle. Removing and adding new easy handles will not affect the pool of connections or the ability to do connection re-use.
也就是说,只要我把一个我们打开的libcurl cp通过curl_multi_add_handle加入到并行队列,这个cp就会使用libcurl multi自己管理的共享连接池,不会受Yar自己管理的persistent与否影响了。而这个共享是指在整个一次libcurl multi的请求过程中的共享,但事实上因为我们一次会发出所有请求,不会存在一个请求完成下一个请求开始的情况,那么也就不会存在复用了。
不过,我后来观察到在某些版本之上的libcurl,比如我测试的7.58.0下,可以看到加速的效果(这个是本机测试,所以看起来速度快很多):
Num 1 costs: 0.0017080307006836s
Num 1 costs: 0.0010600090026855s
后续有时间需要慢慢研究下,从libcurl哪个版本开始的变化。
自定义DNS
这个是来自HuangeChaodian网友的PR,基本上是有的时候,我们需要自定义某个Host的DNS解析结果,比如在测试的时候,把一个Hostname指向本地。
诚然,我们可以使用编辑hosts来达到这个效果, 但如果能在代码中切换,还是会方便不少,看例子:
<?php
$client = new Yar_Client("http://remote_host/index.php");
$client->setOpt(YAR_OPT_RESOLVE, "remote_host:80:127.0.0.1");
这样,Yar就会把remote_host解析为127.0.0.1了, 可以方便我们做一些本地调试。
性能优化
我现在发现,我写的代码随着时间的变化性能提升还是很明显的, 因为Yar写的比较晚, 相对来说可优化的点不多, 于是就简单点做了一些小修补,就不提了,:)
最后,2.1.0 已经发布Yar-2.1.0.
Enjoy!
来源:oschina
链接:https://my.oschina.net/u/4409634/blog/3209301