让你的Laravel在 15 毫秒内返回一个"hello world!"

首先,我认为通过返回最基本的Hello world!字符串,是所有以Laravel为框架的项目中,最基本的一个请求过程。除此以外,项目中的任何http请求,都会带有更多的业务逻辑和数据库查询等耗时操作,且这些逻辑的执行时间都是不可控和不可对比的。也就是说,其他任何请求都不会比返回一个Hello world!字符串更短的时间了。所以,通过对比这个最基本的Hello world请求响应时间,我们可以看出,不同的优化对于Laravel框架从启动到执行结束的影响。

测试参数

参数 版本
服务器 1c处理器,1G内存,1M带宽
PHP版本 8.0
进程管理 PHP-FPM

默认配置响应时间

让你的Laravel在 15 毫秒内返回一个"hello world!"

可以看出,在安装PHP后,默认配置情况下,返回一个Hello world!平均需要140ms左右。接下来,我们开始搞事情了!

Round 1:Laravel 缓存

Laravel为我们提供了很方便的artisan命令来开启缓存功能,有效的减少了文件读取次数。其中php artisan optimize命令包括了php artisan config:cachephp artisan route:cache命令,但是会多出现一个Files缓存。将下面的 5 个命令依次执行:

root@Aliyun-ECS / # php artisan optimize
root@Aliyun-ECS / # php artisan config:cache
root@Aliyun-ECS / # php artisan event:cache
root@Aliyun-ECS / # php artisan route:cache
root@Aliyun-ECS / # php artisan view:cache

我们再看下响应时间:

让你的Laravel在 15 毫秒内返回一个"hello world!"

可见Laravel的缓存对于最基础的请求,没有明显的影响。

Round 2:开启 opcache

这次,我决定使用提速效果最明显的手段:开启opcache扩展。由于本人是使用的 remi 源安装的php8,所以我这里安装opcache扩展会比较容易,其他版本的安装请自行 Google。

root@Aliyun-ECS / # yum install php80-php-opcache

等待安装结束后,我们重启php,然后看下扩展是否已经安装上:

root@Aliyun-ECS / # systemctl restart php80-php-fpm
root@Aliyun-ECS / # php -i|grep opcache.enable
opcache.enable => On => On
opcache.enable_cli => On => On
opcache.enable_file_override => Off => Off

ok,已经开启opcache扩展了,我门再来看下Hello world!的响应时间:

让你的Laravel在 15 毫秒内返回一个"hello world!"

OHHHHHH!效果太明显了,一下子降到 30ms 以内,提升足足有将近 5 倍 的响应时间。注意一下,在第一次请求时,会比较慢,是因为opcache在写缓存导致的,访问过一次以后,速度就飞起了。到这里你就满足了吗?看看文章标题,我们要进一步加大力度!

Round 3:开启 swoole

swoole模块大家都懂,就是将应用程序提前加载到内存中,从而在处理请求时,减少文件的读取和加载过程,为PHP插上了翅膀。下面安装swoole扩展,其他版本的请自行 Google。

root@Aliyun-ECS / # yum install php80-php-pecl-swoole

老样子,安装完后检查下是否安装成功:

root@Aliyun-ECS / # systemctl restart php80-php-fpm
root@Aliyun-ECS / # php -i|grep swoole.enable
swoole.enable_coroutine => On => On
swoole.enable_library => On => On
swoole.enable_preemptive_scheduler => Off => Off

扩展已经启用了,但是还无法进行测试。因为 swoole 是一个 cli 模式下的扩展,php-fpm无法使用。所以我们需要实现一个cli模式下的http应用。但实际上我们无需自己手动编写http应用,社区中有大佬已经写好了。所谓「前人种树,后人乘凉」,我们引入 laravel-swoole 软件包,再启动一个http服务即可,很简单。

// 引入软件包
root@Aliyun-ECS / # composer require swooletw/laravel-swoole
// 发布配置文件
root@Aliyun-ECS / # php artisan vendor:publish --tag=laravel-swoole

执行以上两步操作后,即可在项目的config目录下找到swoole_httpswoole_websocket两个配置文件。一个基本的Hello world!测试,无需修改默认配置,我们只在项目的.env文件中,添加SWOOLE_HTTP_HOST=0.0.0.0SWOOLE_HTTP_PORT=2020即可,意思是在2020端口启动一个http监听程序。0.0.0.0指任何IP都可远程访问。

// .env
SWOOLE_HTTP_HOST=0.0.0.0
SWOOLE_HTTP_PORT=2020

基本配置修改完成,我们启动laravel-swoolehttp应用:

root@Aliyun-ECS / # php artisan swoole:http start
Starting swoole http server...
Swoole http server started: <http://0.0.0.0:2020>

此时我们访问2020端口,即可测试使用swoole扩展后的应用。再看下请求的响应时间:

让你的Laravel在 15 毫秒内返回一个"hello world!"

好家伙!直接干到15ms以内。这里第一次时间较长,是因为开了opcache的原因,会写入缓存。但这里的opcache写缓存,要比Round 2那个只开启opache扩展要快很多,这都是swoole的功劳。

结语

我又测试了一下,单独只启用swoole扩展,不启用opcache,发现响应时间和两个扩展都开启的响应时间一样。也就是说,有了swoole后,opcache就没用了?这个还得请各位大佬指点了。这里简单的做个对比:

让你的Laravel在 15 毫秒内返回一个"hello world!"

通过实践对比,发现同时开启opcacheswoole扩展,是响应时间最快的。

其他问题

感谢

感谢 @Hesunfly 的解答。有时在命令行中用php -i模式查看扩展信息,和在页面中使用phpinfo()查看的扩展信息会有不一致的情况。这里引用下 @Hesunfly 原话:
「有的发行版确实是 clifpm 的配置公用的,例如 mac 使用 brew 安装的 php 就是只有一个 php.ini。 但是我在 centos 和 ubuntu 下安装的一般是区分了clifpm 的。」
file

本作品采用《CC 协议》,转载必须注明作者和本文链接
再见了妈妈今晚我就要远航,别为我担心我有快乐和智慧的桨~
本帖由系统于 2年前 自动加精
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 27

针对 有了 swoole 后,opcache 就没用了 这个问题

OPcache

  1. OPcache是通过将 PHP 脚本预编译的字节码存储到共享内存中来提升 PHP 的性能
  2. 通过opcache_get_status(true)可获取已被编译的文件
  3. 当代码中执行includerequire时,此时并未重新编译php文件,而是读取的OPcache缓存.

Swoole

  1. Swoole应用在执行start()后会将基础扩展存储在共享内存中
  2. Swoole应用在第一次includerequire其他扩展后,会将其编译后保存在内存中

结论

  1. 开启OPcache会提高Swoole初次开启速度以及重启速度
  2. 开启OPcache会提高Swoole初次加载非基础扩展

个人见解,如有不准确请斧正,谢谢

www.php.net/manual/zh/book.opcache...
https://wiki.swoole.com/#/question/swoole?id=swoole-%e9%a1%b9%e7%9b%ae%e8%b5%b7%e6%ba%90%e5%92%8c%e5%90%8d%e5%ad%97%e7%94%b1%e6%9d%a5

2年前 评论

针对 有了 swoole 后,opcache 就没用了 这个问题

OPcache

  1. OPcache是通过将 PHP 脚本预编译的字节码存储到共享内存中来提升 PHP 的性能
  2. 通过opcache_get_status(true)可获取已被编译的文件
  3. 当代码中执行includerequire时,此时并未重新编译php文件,而是读取的OPcache缓存.

Swoole

  1. Swoole应用在执行start()后会将基础扩展存储在共享内存中
  2. Swoole应用在第一次includerequire其他扩展后,会将其编译后保存在内存中

结论

  1. 开启OPcache会提高Swoole初次开启速度以及重启速度
  2. 开启OPcache会提高Swoole初次加载非基础扩展

个人见解,如有不准确请斧正,谢谢

www.php.net/manual/zh/book.opcache...
https://wiki.swoole.com/#/question/swoole?id=swoole-%e9%a1%b9%e7%9b%ae%e8%b5%b7%e6%ba%90%e5%92%8c%e5%90%8d%e5%ad%97%e7%94%b1%e6%9d%a5

2年前 评论

多看书多学习,少学别人起这种标题

3年前 评论
LiamHao (楼主) 3年前

没 swoole,远程服务器 ping 25 ms,执行 42 ms,我很满足了 :blush:

3年前 评论
LiamHao (楼主) 3年前

swoole不是需要和Laravel集成才行么,就打开就行了?

3年前 评论
LiamHao (楼主) 3年前

楼上+1我看得也是挺晕的~~,opcache 关闭需要重启 PHP-FPM 才行,所以你可能一直用的都是opcache

3年前 评论
LiamHao (楼主) 3年前
Hesunfly

在这里只看出来他安装了swoole扩展,到底怎么用的没看到,而且使用php -i 看到的也是cli模式下的php的配置,这里用的却是fpm

3年前 评论
Hesunfly (作者) 3年前
LiamHao (楼主) 3年前
mysql 3年前
LiamHao (楼主) 3年前

看一下你自己配置的哪里啊

php --ini 
3年前 评论
LiamHao (楼主) 3年前

受益匪浅。收藏了。

3年前 评论

github.com/lizhichao/one 就 OPcache 就能快到 1ms ,不用 swoole

2年前 评论
LiamHao (楼主) 2年前
探索者 (作者) 2年前
LiamHao (楼主) 2年前

php artisan swoole:http start这个命令启动后swoole就一直开启了吗,不用管了吗

2年前 评论
LiamHao (楼主) 2年前
xiaohuasheng (作者) 2年前
Fell-boy 2年前
xiaohuasheng (作者) 2年前
flc1125

swoole、opcache 其实都是将文件载入到内存里了,所以执行上会更快。

一般这方面的测评用一些压测工具会更具参考性 :smile:

附:将 Session 等一些无用服务去掉,可能会更快


:+1: :+1: 鼓励探索精神,加油~

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!