惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

月光博客
月光博客
IT之家
IT之家
Hugging Face - Blog
Hugging Face - Blog
J
Java Code Geeks
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 叶小钗
MyScale Blog
MyScale Blog
G
Google Developers Blog
Microsoft Azure Blog
Microsoft Azure Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
大猫的无限游戏
大猫的无限游戏
博客园 - 三生石上(FineUI控件)
Google DeepMind News
Google DeepMind News
Engineering at Meta
Engineering at Meta
The Cloudflare Blog
Martin Fowler
Martin Fowler
酷 壳 – CoolShell
酷 壳 – CoolShell
N
Netflix TechBlog - Medium
MongoDB | Blog
MongoDB | Blog
I
InfoQ
WordPress大学
WordPress大学
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
H
Help Net Security

风雪之隅

Yac 2.4.0发布 - 小值读取性能提升64% 用Yac给WordPress做缓存:比Memcached快19% Laruence Laruence Laruence Laruence Laruence 深入理解PHP7内核之OBJECT - 风雪之隅 PHP 8新特性之Attributes(注解) - 风雪之隅 博客迁移到腾讯云 - 风雪之隅 在Qcon 2015 北京上的演讲PPT - PHP7 Yaf and Phalcon, which is faster? HTTPOXY漏洞说明 - 风雪之隅 一个关于Zend O+的小分享 - 风雪之隅 在PHP中使用协程实现多任务调度 - 风雪之隅 Curl的毫秒超时的一个"Bug" - 风雪之隅 PHP8.0的Named Parameter - 风雪之隅 关于PHP,关于Realsee - 风雪之隅 PHP8新特性之match表达式 - 风雪之隅 PHP 8新特性之JIT简介 - 风雪之隅 使用SSE2指令高效实现strtolower - 风雪之隅 使用OSC52实现iTerm2远程pbcopy - 风雪之隅 Yaf 3.2 发布 - 风雪之隅 使用PHP Socket开发Yar TCP服务 - 风雪之隅 Yac 2.1 升级说明 - 风雪之隅 Yaf-3.1 10%性能提升版 - 风雪之隅 Yaconf-1.1 40%速度提升版 - 风雪之隅 PHP FFI详解 - 一种全新的PHP扩展方式 - 风雪之隅 使用SSE2指令集加速字符替换 - 风雪之隅 Yaf_Loader重构测试 - 风雪之隅
Yar-2.1 新功能介绍 - 风雪之隅
Prestige par · 2023-07-13 · via 风雪之隅

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!