使用 Opcache 优化 Laravel 的性能

发布时间: 2018-12-27 12:56:13 作者: 大象笔记

Laravel 令人头疼的性能问题

昨天上午,同事在测试一个知识 PK 的小程序,在 2~3 同时在线的情况下,服务器 CPU 居然达到了 60%,触发了阿里云钉钉报警。。。

一个非常简单的 API 接口,虽然写的逻辑确实比较啰嗦,但是一秒钟不超过 5 个请求的情况下,Laravel 硬是把 CPU 彪到了 60%。

这个性能确实让人无法接受,简直是玩具,根本不满足上线的基本要求。

确认是接口逻辑问题还是 Laravel 的问题

为了确认是接口的逻辑问题,还是 Laravel 的问题。我们做了一些简单的对比测试。

测试的对象是两个不同的 Laravel 项目下的相同功能的 API,例如,这里测试的是一个用来返回服务端版本号的接口。逻辑完全相同。

sudo apt install apache2-utils
time ab -c 10 -n 100 ‘https://something1.com/api/get_version’
time ab -c 10 -n 100 ‘https://something2.com/api/get_version’

结果令人意外,两个不同项目的同一个接口,性能差异巨大。

所以,问题应该不是接口的逻辑问题,而是 Laravel 的性能问题。

鸡肋的 route cache 及 config cache

php artisan route:cache
php artisan config:cache

按照网上的推荐,使用了 laravel 的 cache 机制,CPU 的问题并没有得到解决。可以说毫无效果。

一些尝试

然后,效果也都不明显。

Laravel 作者推荐的 opcache

Laravel 作者似乎对网上抨击 Laravel 的渣性能问题有非常大的不满。所以,他亲自做了一个测评,并做了如下优化配置:

原文在这里 https://medium.com/@taylorotwell/benchmarking-laravel-symfony-zend-2c01c2b270f8

结果居然是 Laravel 在与 Zend, Symfony 的对决中胜出。。。

当然,对比的结果我不太关心,我关心是,laravel 居然能跑出 600 req/s 的成绩。。。

于是,我决定尝试一下 opcache

启用 opcache

vim /etc/php/7.0/fpm/php.ini

opcache.enable=1
opcache.memory_consumption=512
opcache.interned_strings_buffer=64
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0
opcache.save_comments=1
opcache.fast_shutdown=1

修改之后,重启 fpm 服务

service php7.0-fpm reload

重新测试,发现并发量提升了 10 倍后,CPU 稳稳的控制在了 50%。。。

性能提升惊人。

opcache 的原理

首先需要了解的是 Laravel 为何会导致 CPU 飙高。

PHP 代码的执行过程是:

  1. Nginx 等 web server 收到 request 请求具体的 PHP 文件
  2. Zend引擎读取.php文件
  3. Lexicon sacn:扫描其词典和表达式
  4. Parse:解析文件
  5. 创建要执行的计算机代码(称为Opcode)
  6. 返回

所以,问题就很明显了吧,从第三步到第五步,都是耗费 CPU 的操作。而且每个请求都要重复一遍。而这些操作对于静态语言来说本来应该是在编译时该执行一次的操作。但是对于 PHP 就需要重复这个流程。

而 opcache 所做的事情就是将 3 ~ 5 步的结果进行缓存,如果 php 文件不发生更改,那么就不重复这3步操作,直接读取内存中的缓存。

那么,显然 CPU 使用率就必然会降下来。

opcache 需要注意的地方

每次更新了代码,需要重启 fpm 服务,以更新 cache。

持续的优化策略

即使开了 opcache,在业务的并发请求突增的情况下,Laravel 自然还是抗不住。所以,一种可行的优化策略是

参考

我是一名山东烟台的开发者,联系作者