1

Yar-2.1 新功能介绍

 3 years ago
source link: https://www.laruence.com/2020/03/16/5578.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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调用,我们来看个例子:

  1. <?php
  2. function bench($client) {
  3.     $start = microtime(true);
  4.     $client->header("connection");
  5.     echo microtime(true) - $start, "s\n";
  6. $client = new Yar_Client("http://remote_host/index.php");
  7. $client->setOpt(YAR_OPT_PERSISTENT, 1);
  8. bench($client);
  9. bench($client);
  10. bench($client);
  1. 0.090613842010498s
  2. 0.045492887496948s
  3. 0.045512914657593s

可见,第二次调用的时候,耗时降低了一半,这是因为节省了TCP链接建立的耗时。

最后,链接会在PHP请求结束以后,整体释放,也就是PHP请求生命期的存活,不会垮请求,也不用担心内存泄漏。

不过很遗憾,这个并不能用于加速并行调用:

  1. function callback($retval, $callinfo) {
  2.     global $start;
  3.     if ($callinfo) {
  4.         echo "Num ", $callinfo["sequence"] , " costs: ", microtime(true) - $start, "s\n";
  5. Yar_Concurrent_Client::call("http://remote_host/index.php", "header", array("connection"), NULL, NULL, array(YAR_OPT_PERSISTENT=>1));
  6. $start = microtime(true);
  7. Yar_Concurrent_Client::loop("callback", function($error) { var_dump($error); });
  8. $start = microtime(true);
  9. Yar_Concurrent_Client::loop("callback", function($error) { var_dump($error); });

我们会发现俩次调用没有加速的效果:

  1. Num 1 costs: 0.091023921966553s
  2. 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下,可以看到加速的效果(这个是本机测试,所以看起来速度快很多):

  1. Num 1 costs: 0.0017080307006836s
  2. Num 1 costs: 0.0010600090026855s

后续有时间需要慢慢研究下,从libcurl哪个版本开始的变化。

自定义DNS

这个是来自HuangeChaodian网友的PR,基本上是有的时候,我们需要自定义某个Host的DNS解析结果,比如在测试的时候,把一个Hostname指向本地。

诚然,我们可以使用编辑hosts来达到这个效果, 但如果能在代码中切换,还是会方便不少,看例子:

  1. <?php
  2. $client = new Yar_Client("http://remote_host/index.php");
  3. $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!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK