年前花了点时间,对Yar的性能做了一些做了一些提升,但是也遇到一个让我有点不舒服的当初没有良好设计遗留的问题,就是在并行调用RPC的时候,现在的方法原型是: public static Yar_Concurrent_Client::call(string $uri, string $method, ?array $arguments = NULL, ?callable $callback = NULL, ?callable $error_callback = NULL, ?array $options = NULL):null|int|bool {} 是不是一看就很头大?
从PHP8.0之后,我参与PHP开源就少了,从而博客也写的少了,不少朋友来问,所以觉得有必要用一篇文章说明下近况。 总的来说,本职工作发生了一些变化,导致工作上的事情,牵扯了太多的精力,从而没有办法有太多的精力投入PHP开源工作中。 而关于,工作的变化,我稍微详细的介绍下:
PHP8 alpha2发布了,最近引入了一个新的关键字:match, 这个关键字的作用跟switch有点类似。 这个我觉得还是有点意思,match这个词也挺好看,那么它是干啥的呢?
这个本来是之前在微博上有个同学说他经常用来面试别人,大概是说,对于如下代码,你觉得会输出啥: $a = true; if ($a) { echo "true"; } else label: { echo "false"; } 当时没想写,今天中午又有人问我,我想那就介绍下这个原因吧.
PHP8 alpha1已经在昨天发布,相信关于JIT是大家最关心的,它到底怎么用,有什么要注意的,以及性能提升到底咋样?
PHP的类名,函数,方法名是不区分大小写的,也就是说无论你怎么定义函数名,实际上在引擎层面查找的时候都是会统一转换成小写形式来做的。 也就是说strtolower的应用是非常普遍的。 当然,PHP也做了很多的设计来避免对字符串做过多的字符串小写操作,比如如果我们在PHP代码中写下: CamelFunc(); 这样的函数调用的时候, PHP会在编译时刻就把CamelFunc全部小写,然后存储在原始字面量之后(PHP-5.4 literals)。
PHP8的Alpha版本,过几天就要发布了,其中包含了不少的新特性,今天呢,我想谈谈Attributes,为啥呢, 是昨天我看到很多群在转发一个文章,叫做《理解PHP8中的Attributes》,说实在的,这篇文章应该是直接从英文翻译过来的,写的晦涩难懂,很多同学看完以后表示,看的一头雾水,不知道在说啥。 于是我想,就用一篇文章来简单说说这是个啥。
最高效的码字方式,一定有一个特点,那就是手指离开键盘的次数尽可能的少。 并且手指码字的时候的在键盘的跨度尽可能的短, 这也是我认识不少老牌程序员用Vim也不用ESC, 而是使用ctrl+[, 甚至还有....
经过俩周多的重构,终于一咬牙今天发布了Yaf 3.2.0 beta, 要不然一直在想各种可能的优化点,不停的写,没完了, :) 这次的重构的最初出发点是把原来的Yaf对象从PHP的原生对象,改成了自定义的对象:
Yar支持HTTP和TCP俩种Transporter, HTTP的是基于CURL,PHP中的Yar默认就是走的HTTP Transporter, 这个大家应该都不陌生, 但是基于TCP的, 可能大家会用的少一些。 今天我们尝试用PHP来写一个TCP的Server,来介绍下如何实现对Yar RPC协议的处理, 这个例子可以方便的结合Swoole等异步PHP框架,实现一个高性能的Yar TCP Server。 这个过程中, 会让大家了解Yar的RPC通信协议,以及捎带了解下Socket编程。
Yac (Yet Another cache)也是之前我在微博的时候开发的一个为PHP使用的,Lock-free, Shared Memory, User Data Cache,用来替代当时微博在PHP机器上装的本地Memcache, 因为当时的需求特点,最初做了完全无锁的设计,但是这样有一个隐患就是用户有可能获得“错误”的数据,虽然之前的测试概率非常非常低。 关于Yac的设计,可以参考我7年前写的Yac (Yet Another Cache) - 无锁共享内存Cache。 作为我的Ya全家桶的重要一员, 在我优化完一轮Yaf, Yar, Yaconf以后,Yac当然也不能少了。
前面的几篇,我系统的介绍了PHP7以后的ZVAL, Hashtable, 以及Reference, 今天我来讲讲Object(对象)的一些变化。 按照惯例,我先带大家回顾下PHP5时的zend_object(此部分内容之前的文章中也有涉及,如果熟悉可以跳过), 之前如果有兴趣也可以看看我10年前写的深入理解PHP原理之对象.
Yar(Yet Another RPC framework)是一个轻量级支持并行调用的PHP RPC框架,是我还在微博的时候为了优化微博的性能而开发的一个工具,Yar的并行调用在微博被大量应用以降低用户请求耗时。 最近还是因为疫情,我把Yaf,Yaconf都优化了一轮,今天也完成了Yar的优化(事实上,Yar之前写的就还不错,没啥可优化的,哈哈),也新增了俩个能力。我来简单介绍下:
Yaf(Yet Another Framework)是我的第一个发布的PECL扩展,也是我走上PHP内核维护的开始,我一直对它比较有感情,Yaf在过去的8年多时间里,也得到了不少朋友的喜爱,当然Yaf还是有很多不足,但毕竟Yaf主要还是针对性能场景,不能满足所有的需求。 即然Yaf == 性能,借着疫情的在家时间,又花了一些时间对Yaf做了一轮优化,希望能对性能有进一步的提升。
Yaconf是一个高性能的PHP配置容器, 它在PHP启动的时候把格式为INI的配置文件Parse后存储在PHP的常驻内存中,不需要每次请求的时候都来分析配置文件,并且在获取配置项的时候"zero-copy",具体的介绍可以看我2015年发布的时候写的介绍:Yaconf - 一个高性能的配置管理扩展。 最近因为疫情,我对Yaconf做了一系列的重构,主要是减少取过程中的内存使用,基本重写了整体的逻辑,那性能优化的结果如何呢? 我们来做个简单的测试。
随着PHP7.4而来的有一个我认为非常有用的一个扩展:PHP FFI(Foreign Function interface), 引用一段PHP FFI RFC中的一段描述: For PHP, FFI opens a way to write PHP extensions and bindings to C libraries in pure PHP. 是的,FFI提供了高级语言直接的互相调用,而对于PHP来说,FFI让我们可以方便的调用C语言写的各种库。
这个算是一个比较有用的性能优化技巧吧,主要是刚刚在重构Yaf_Loader的时候又用到,想着这个操作比较常见,就专门拎出来做个小分享... 我们在写代码的时候,在字符串处理的时候,可能会遇到这样的需求,就是把一个目标字符串中所有出现的某个字符a替换为另外一个字c....
自动加载器在一个大型PHP项目中,往往是最容易被忽视的性能点,因为它一般而言都很简单, 但是它的调用次数确实非常之大。Yaf也不例外,虽然Yaf是C语言写的扩展,但还是可能会占到一个复杂项目1%到3%的耗时,这俩天想了想,总不能天天开会写博客吧,还是写点代码吧?于是乎决定启动重构。:) 经过周末一番重构,我基本上重写了Yaf_Loader::autoload整条生命期, 目的就是降低内存分配,具体的变化可以看:Refactor Yaf_Loader, 效果咋样? 我们来做个简单的测试:
刚刚吃饭的时候想说今天再写点啥? 突然想起来前几天有人在微博上评论我的一个PHP的面试题: var_dump(PHP_INT_MIN); var_dump(-9223372036854775808); 输出一样么? 如果不一样为什么? 我认为这样的题目作为PHP面试题并不合适。 不过作为一个有趣的知识点,我今天就说说这个小问题吧。
从PHP7开始,大家可能会发现,不少函数不再使用传统的参数处理方式,而是改用了我们称之为Fast zend parameters parsing(FAST_ZPP)的新型方式, 比如在PHP7之前,count函数是这样的: PHP_FUNCTION(count) { zval *array; long mode = COUNT_NORMAL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &array, &mode) == FAILURE) { return; } .... } 在PHP7以后,就变了样了...
之前的俩篇文章深入理解PHP7内核之zval 和深入理解PHP7内核之Reference, 我介绍了当时在开发PHP7的时候对zval和reference的一些改造思考和结果, 之后因为确实精力有限就没有继续往下写,时隔一年多以后,因为这场突如其来的疫情,在家办公的时间很多, 于是终于有了时间让我来继续介绍一下PHP7的中Hashtable的变化, 以及当时我们做这些变化背后的考量.
一个问题, var_dump(1...9)输出什么? 动手验证下: php -r “var_dump(1...9)”; string(4) "10.9" 输出10.9, 乍一看这个var_dump的输出很奇怪是不是? 为什么呢?
博客迁移完腾讯云以后, 又配置好了ssl,一直在调优PHP的性能,中午调整了半天fpm和opcache, 晚上又突然想起来我之前在某个大会上分享过的使用tmpfs(把内存当成硬盘)来加速网站的做法,于是~搞!
主要是因为原来的SAE有点贵了,3个月1000块,于是在腾讯云搞了一个服务器 :< 从头搭建环境,mysql, nginx, php, memcahced, wordpress,wp-plugins, themes, ssl, 折腾了一晚上, 中间被个nginx的rewrite和try_files的问题折腾了半天。后来又被ssl折腾了半天..... 博客开了12年了,终于跟随潮流,配置好了ssl和http2... enjoy:)
这个源自于一个看似很诡异的问题: if (print("1\n") && print("2\n") && print("3\n") && print("4\n")) { ; } 你期待这段代码输出什么呢?
经常会有人被strtotime结合-1 month, +1 month, next month的时候搞得很困惑, 然后就会觉得这个函数有点不那么靠谱, 动不动就出问题. 用的时候就会很慌... 这不, 刚刚就有人在微博上又问我: 鸟哥,今天是2018-07-31 执行代码: date("Y-m-d",strtotime("-1 month")) 怎么输出是2018-07-01? 好的吧, 虽然这个问题看起来很迷惑, 但从内部逻辑上来说呢, 其实是"对"的, 你先别着急哈, 让我慢慢讲
上一章说过引用(REFERENCE)在PHP5的时候是一个标志位, 而在PHP7以后我们把它变成了一种新的类型:IS_REFERNCE. 然而引用是一种很常见的应用, 所以这个变化带来了很多的变化, 也给我们在做PHP7开发的时候, 因为有的时候疏忽忘了处理这个类型, 而带来不少的bug.
PHP7已经发布, 如承诺, 我也要开始这个系列的文章的编写, 主要想通过文章让大家理解到PHP7的巨大性能提升背后到底我们做了什么, 今天我想先和大家聊聊zval的变化. 在讲zval变化的之前我们先来看看zval在PHP5下面是什么样子
PHP 是 Web 开发最常用的语言,每个大版本的更新都带来不少新特性和性能提升。特别是 PHP 7.0 的发布,带来 PHP 性能飞跃。本文作者对各个 PHP 版本进行了 CPU 性能基准测试,并且带来了PHP下个大版本的消息。本文中文版由高可用架构志愿者翻译。
好久没写文章了, 博客都长草了, 早上起来本来想去上班, 一看这么大雨, 这要上路了不得堵死啊. 再加上有同学对我昨天转发的微博HTTPOXY漏洞表示不理解, 问会不会影响普通应用, 于是就写篇文章介绍下, 等早高峰过了吧;)..... 不过要注意的是, 这里我只是介绍PHP这个角度, 关于Go和Python等其他角度的,因为我也不是"很"懂,你们还是看原文吧 :)
PHP7已经发布了, 作为PHP10年来最大的版本升级, 最大的性能升级, PHP7在多放的测试中都表现出很明显的性能提升, 然而, 为了让它能发挥出最大的性能, 我还是有几件事想提醒下.
这是我写在微信公众号里的一篇感想, 突然想起来博客好久没更新了, 感慨一下现在的产品发展的, 个人博客好像越来越没有存在的价值了.... 唉, 不管怎么说, 我稍微做了一些修改以后, 转贴过来.. 做开源也有4, 5年的时间了, 从最初的Yaf, 到今天的PHP7, 我参与的项目越来越多, 使用我代码的用户也越来越多, 而昨天发布的PHP7, 绝对是我从事开源以来的一个最重要里程碑, 我应该纪念一下今天, 就让我稍微感性一次吧.
PHP7刚刚发布了RC4, 包含一些bug修复和一个我们最新的性能提升成果(NEWS), 那就是"HugePageFy PHP TEXT segment", 通过启用这个特性,PHP7会把自身的TEXT段(执行体)”挪“到Huagepage上,之前的测试,我们能稳定的在Wordpress上看到2%~3%的QPS提升。 关于Hugepage是啥,简单的说下就是默认的内存是以4KB分页的,而虚拟地址和内存地址是需要转换的, 而这个转换是要查表的,CPU为了加速这个查表过程都会内建TLB(Translation Lookaside Buffer), 显而易见如果虚拟页越小,表里的条目数也就越多,而TLB大小是有限的,条目数越多TLB的Cache Miss也就会越高, 所以如果我们能启用大内存页就能间接降低这个TLB Cache Miss,至于详细的介绍,Google一搜一大堆我就不赘述了,这里主要说明下如何启用这个新特性, 从而带来明显的性能提升。
我们一直致力于提升PHP7的性能, 上个月我们注意到GCC的PGO能在Wordpress上能带来近10%的性能提升, 这个让我们很激动. 然而, PGO正如名字所说(Profile Guided Optimization 有兴趣的可以Google), 他需要用一些用例来获得反馈, 也就是说这个优化是需要和一个特定的场景绑定的. 你对一个场景的优化, 也许在另外一个场景就事与愿违了. 它不是一个通用的优化. 所以我们不能简单的就包含这些优化, 也无法直接发布PGO编译后的PHP7. 当然, 我们正在尝试从PGO找出一些共性的优化, 然后手工Apply到PHP7上去, 但这个很明显不能做到针对一个场景的特别优化所能达到的效果, 所以我决定写这篇文章简单介绍下怎么使用PGO来编译PHP7, 让你编译的PHP7能特别的让你自己的独立的应用变得更快.
这个项目其实不是一个新的idea, 这个是我在来微博以后, 第一个优化项目中顺手做的一个小工具, 本身叫做Weibo_Conf. 但是因为Weibo_Conf是属于Weibo扩展的, 里面还有一些其他功能是专门为Weibo定制的. 所以不适合直接开源. 随着PHP7的发布, 新增了很多持久化类型的支持比如IS_IMMUTABLE_ARRAY, 于是我就在PHP7下重新开发了Yaconf, 开源出来, 方便大家使用.
PHP5.5一个比较好的新功能是加入了对迭代生成器和协程的支持.对于生成器,PHP的文档和各种其他的博客文章已经有了非常详细的讲解.协程相对受到的关注就少了,因为协程虽然有很强大的功能但相对比较复杂, 也比较难被理解,解释起来也比较困难. 这篇文章将尝试通过介绍如何使用协程来实施任务调度, 来解释在PHP中的协程. 我将在前三节做一个简单的背景介绍.如果你已经有了比较好的基础,可以直接跳到“协同多任务处理”一节.
这个问题, 早在1年前就遇到了, 当时因为没有在意一直没有跟进. 最近团队来了个新人, 又一次触发了这个问题, 所以终于下定决定要好好找找这个BUG的原因.. 首先,这篇文章是个流水账, 没啥意思, 其次最终我其实也没能真正找到原因, 只是找到了一个规避的方法, 和一个猜测的原因. 万一遇到类似情况的同学可以部分借鉴, 当然, 最后我是希望有人对glibc源码熟悉的同学, 可以真正的指点下这个bug的真实原因是啥. 问题是这样的, 我们的一个服务, 依赖于Yar C库, 但是valgrind检测会报告一个问题:
不少同学对于PHP7, 还是了解的不多, 这次在Qcon 2015 北京上我做了一个关于PHP7的分享, 主要内容是PHP7的主要新特性和大幅的性能提升(已经和HHVM的性能不相伯仲). 重点是介绍我们都做了那些性能优化手段, 最后的成果是咋样. 虽然之前在微博上发过, 但是还是有人不时的私信问我PPT, 考虑到微博对搜索引擎的不友好, 我就把PPT发这里吧.
前天看了TimYang的一个技术从业人员眼中的2014> , 有些观点我很是赞同, 于是我也有了想写点什么的冲动... 在2015年的第二天, 我终于好像有了一些跳跃的想法, 可以说给大家听听. 也许不够体系, 不够完整, 但或许能得到一些共鸣.
其实我已经在很多场合说过, PHP7的性能已经和HHVM相当了.. 但是呢, 总是有人问... 另外感觉微博并不能特别好的留存, 所以我写个BLOG吧. 这篇BLOG, 我将进行最客观的对比测试, 就用ab来压测一下Wordpress的首页.. 来对比看看PHP7和HHVM-3.2.0的性能在Wordpress上的性能对比.
本来是发在长微博的, 不过, 鉴于, 好久没更新博客了...... 就转过来, 凑个数吧, 大家凑合着看 :) 白忙活了近2个小时,不吐不快: 一切要从今天下午5点左右说起, 调试一个扩展, 用valgrind(valgrind-3.8.1)做例行检查, 很不幸的valgrind报告invalid read:
最近我们的服务在升级php使用的libcurl, 期望新版本的libcurl支持毫秒级的超时, 从而可以更加精细的控制后端的接口超时, 从而提高整体响应时间. 但是, 我们却发现, 在我们的CentOS服务器上, 当你设置了小于1000ms的超时以后, curl不会发起任何请求, 而直接返回超时错误(Timeout reached 28). 原来, 这里面有一个坑, CURL默认的, 在Linux系统上, 如果使用了系统标准的DNS解析, 则会使用SIGALARM来提供控制域名解析超时的功能, 但是SIGALARM不支持小于1s的超时, 于是在libcurl 7.28.1的代码中...
这个是我上周末在"阿里PHP技术沙龙"临时分享的一个主题的PPT, 主要是介绍一下Zend Optimizer Plus(简称O+). O+是由Zend公司开发的一个PHP性能提升工具, 在PHP5.5开始, 已经随着PHP的源代码一起发布了, 并且也改名为:Opcache. 不同于APC, O+除了是Opcodes Cache以外, 还做了很多的Opcodes优化, 这个PPT就是主要列举了一下主要的优化们. 也不同于eacc, O+做的优化更多一些.
这个PPT以前已经在微盘上分享过了, 今天突然想起来, 上传到了slideshare上, 顺便也在博客上留个纪念吧. 这个PPT介绍了过去一年我在微博的工作成果, 包括Yaf的改, 以及新东西Yar, Yac等 通过一系列的努力(整体方针是, 先提速, 降成本, 清晰架构, SOA), 我们让微博首页的响应时间下降了一倍多, 同时还降低了整体的成本.
首先, 太久不更新博客了, 容我先啰嗦几句. 我一直以为人总是会挤出时间写博客的, 但现在看来我错了. 博客很久不更新, 倒不是说没有内容可以分享. 而是这一年来确实忙了很多, 本身工作上的事情就很多, 业余时间也被PHP项目上的事情, Zend的事情填满. 再加上一些小感悟也都在微博上牢骚了... 所以.... Anyway, 很感谢各位经常来我博客的朋友, 不过我建议大家如果是提问的话, 不要在留言里, 有的时候会被博客当做SPAM, 有一些小问题, 可以来微博At我 @laruence 言归正传, 今天分享个前天刚刚做的小工具, 代码可以在我的github上找到: php-valgrind. 这个工具主要是为PHP脚本提供了可以在脚本中开启Valgrind(严格说是Callgrind)的Profile能力.
关于PHP的浮点数, 我之前写过一篇文章: 关于PHP浮点数你应该知道的(All ‘bogus’ about the float in PHP) 不过, 我当时遗漏了一点, 也就是对于如下的这个常见问题的回答: 为啥输出是57啊? PHP的bug么? 我相信有很多的同学有过这样的疑问, 因为光问我类似问题的人就很多, 更不用说bugs.php.net上经常有人问... 要搞明白这个原因, 首先我们要知道浮点数的表示
好久没有更新blog了, 这一年来的工作确实很忙..... anyway, 今天终于有新东西可以和大家分享. 这个idea来自一个很简单的想法, 以及目前所遇到的一个机会. 首先我们来谈谈这个机会. 在以前, 很多人都会选择使用APC, APC除了提供Opcode Cache以外, 还会提供一套User Data Cache(apc_store/apc_fetch), 所以对于很多有需求使用User Data Cache的同学, 使用APC, 就没什么问题. 然而, 最近Zend Optimizer Plus开源了, 测试表明, Zend O+在Opcode Cache方面, 因为做了Opcode Cache优化, 所以会比APC要高效, 再后来, PHP5.5已经把Zend O+作为了源代码的一部分. 会随着PHP一起发布. 这就有了个问题, 对于那些既要使用Zend O+的Opcode Cache, 又要使用APC的User Data Cache的同学, 怎么办呢? 开始的时候, 我只是给APC增加了一个开关apc.opcode_cache_enable, 这样一来, 用户就可以使用APC然而关闭opcode cache来达到这个目的, 但是APC的User Data Cache使用的存储机制是和Opcode Cache一样的, 这样的场景要求数据严格正确, 所以锁会比较多, 测试表明, APC的User Data Cache的效率和本地memcached几乎相当. 所以, 我想到了这个idea, 单独开发一个基于共享内存的, 高性能的User Data Cache
废话不多说, 直接看代码: prepare($query); $bind_params = array(':username' => "laruence", ':password' => "weibo"); foreach( $bind_params as $key => $value ){ $statement->bindParam($key, $value); } $statement->execute(); 请问, 最终执行的SQL语句是什么, 上面的代码是否有什么问题?
上午的时候, 有同事来找我说上周新上线的一个使用mcrypt的脚本, 响应非常慢, 但是服务器的各项指标都正常, 不知道是什么原因. 经过了解, 一个简单的可重现的脚本如下: 当20个并发请求这个脚本的时候, 我们会发现Apache的响应时间急剧上升... 考虑到这个问题可能具有一定的普遍性, 于是我想我还是写一篇文章来介绍下这个坑, 防止后来人再次踩到.
After Yaf, there comes another PHP framework in extension(在Yaf发布以后, 又出现了一个PHP扩展的框架 Phalcon): Phalcon. then there raise a problem, which people have asked multi-times to me, that is , which one is the *fastest*(于是就出现一个问题, 不停的有人问, 到底Yaf和Phalcon哪个快, 因为他们都在他们的主页上宣称是最快的框架)? Yaf, or Phalcon. as they both declared they are the fastest(Yaf, Phalcon)
You can subscribe to this RSS to get more information