HHVM 中的 RepoAuthoritative 模式

HHVM 3.8 中提出了一个 RepoAuthoritative 模式,用于提升 PHP 代码的效率。

PHP 代码是解释型的,也就是每次执行的时候,PHP 引擎都会读取源代码,编译成机器代码之后再执行。这也就是为什么解释型语言比较慢的原因之一,它不能一次编译完成,而是一定要运行到哪里编译到哪里。编译的过程拖慢了整个运行的效率。而这样每次“编译”的过程显得有些多余,因为代码是基本不会变的。于是 PHP-FPM 是提出了 OpCache 来缓存编译的结果,如果代码已经被编译过,且源代码没有改动,则继续使用缓存。

而 HHVM 则更进了一步,在 RepoAuthoritative 开启之后,指定的文件夹会被编译成一个二进制文件,并同时进行优化。官方说法是,这样的优化可以在 HHVM 本身的基础上,再提升 20% 的运行效率。

开启的方法如下,其中 /var/www 是想要编译的文件夹。

关闭的方法如下:

编译的过程使用了 /var/run 做为临时文件夹,实测 WordPress 编译完成之后,要占用 175MB 的空间,如果 /var/run 太小会提示“disk is full”错误。

当然, RepoAuthoritative 也有一定的限制,比如不能使用 eval() 和 create_function() 等动态改变代码的语句。不过 WordPress 中几乎没有用到,说“几乎”是因为实际上有两处用到了,一个是在 wp-includes/pomo/po.php 中,这个文件貌似根本不会被执行到;另一处是在 wp-includes/atomlib.php 中,只要不使用 atom 作为 RSS feed 即可。另外就是编译完成之后,源代码的改动就会“失效”,要再一次编译才会使改动起作用。

然而,由于 HHVM 自身已经相当地高效了,开启 RepoAuthoritative 模式之后没有明显的变化。本站实测下来,TTFB 时间大概减少了 50ms,对于原本只有 700ms 左右的速度来说,看不出效果。我试用了一下之后就把它关闭了。不过至少说明在 WordPress 上使用这个功能是没有问题的。如果你的 WordPress 中有非常慢的功能,不妨试一下 RepoAuthoritative 模式。

HHVM 近期频繁崩溃

近期 HHVM 频繁崩溃,一天数次,导致博客不稳定。尽管我有一个后台程序重启 HHVM,但毕竟有那么几分钟的不能响应时间,多少有点不爽。于是就研究了一下崩溃的原因。

在 /var/log/hhvm/error.log 中能看到类似下面的信息,Core dump 了:

然后再去看 /tmp/stacktrace.1173.log,发现如下信息:

说是要增加 Eval.JitASize 的大小。Google 了一下,这个数值指定了 HHVM Translation Cache 的大小。对 HHVM 不是特别了解,猜测是 HHVM 会把 PHP 翻译成 HH 的代码,并缓存在 Translation Cache 中。这个 Core Dump 的原因大概就是 Translation Cache 用完了。

根据 Issue #2851 的讨论,在 server.ini 中加入如下设定,把 JitASize 提高到 128M:

讨论中也有人说这个设定并不能完全解决问题,顶多就是把每天一次的崩溃延长到几周一次,后续进一步的完善还在 Issue 5233 中讨论。

HHVM 崩溃后自动重启

不知为何 HHVM 不具备进程保护的能力,也就是说,HHVM 启动之后,只有一个进程,并且崩溃之后没有自主恢复的机制。大概是因为 Facebook 的服务器中有统一的方式来保护各种服务进程,也就没有在 HHVM 中单独做一份。但对于普通用户来说,HHVM 的稳定性有点弱。

今天一早,有位朋友提醒我博客没法留言了,现象是连接中断。后来我排查了一下发现原因是 HHVM 崩溃了,具体的表现有人在 Github 上已经反映过。好在我之前就有所准备,写了一个 Cron Job 定时检查 HHVM 进程,如果进程不在了,就自动重启 HHVM。这个脚本每两分钟运行一次,看来那位朋友不巧,正好撞在那两分钟的枪口上。

检查的脚本是从 Stackoverflow 上抄来的,代码如下:

虽然两分钟的间隔不算完美,但配合上 WP Super Cache 的纯净态支持,可以极大程度上避免博客下线的窘境。真正完美的方式,是开启两个(或多个)HHVM 进程,然后在 Apache 端做一个负载均衡,这样的话,即使有一个 HHVM 进程挂了,也不会影响到博客的使用。网上有人这样试过,但看上去很麻烦的样子,我还是等 HHVM 更新吧。

话说 Facebook 宣布这个月底有一个重大更新,HHVM 3.6,其中包含了很多稳定性方面的修复,值得期待。