提高Laravel应用性能方法详解
使用Laravel做开发是高效而愉悦的体验。
通常,当你准备部署应用的时候,你可能会意识到应用也许会在真实环境下表现不佳。
需要明白的是,没有银弹。通过努力去对应用的每个细节完成所有的优化,速度可能会变慢,但使用下面这些技巧会让你感到恰到好处。
缓存配置文件
laravel的配置项分布在数十个配置文件中,在每次的请求中都将每个文件including进来很消耗性能。为了将所有的配置文件都合并为一个,可以使用:
phpartisanconfig:cache
记住修改了配置文件后不会影响已有的配置文件缓存。为了刷新缓存,可以再次上述的命令。如果你想完全清除缓存,执行:
phpartisanconfig:clear
路由缓存
在laravel中,路由也需要昂贵的开销。用以下命令缓存routes.php文件:
phpartisanroute:cache
请注意,它不适用于闭包。如果你正在使用闭包,这是一个很好的机会将它们移动到控制器中,因为artisan命令在尝试编译绑定到闭包的路径而不是正确的控制器方法时会抛出异常。
与配置缓存相同,对routes.php的任何更改都不会有任何影响。要刷新缓存,请在每次更改路径文件时运行上面的命令。要完全清理干净路由缓存,请运行以下命令:
phpartisanroute:clear
类映射加载优化
在一个中型项目中,存在数百个PHP源文件是很正常的事情,由于良好的编程习惯,我们会把代码做一些分离,每一个php文件都有自己的职责。当然,这并非没有缺点,Laravel必须为每一次请求都加载这数百个文件,这是一件很消耗性能的事情。
因此,一个比较好的办法是声明哪些文件是用户每一次请求(如:服务提供者,中间件等)都需要载入的,然后将这些需要每次加载的文件写入同一个文件中,减少include文件的数量。
这类似于javascript将文件合并为一个没有区别(webpack,gulp),会减少游览器会服务器的请求。
如果需要添加其他的源文件,可以在config/compile.php的fileskey中声明。
当你把需要为每个请求都加载的文件设置好之后,它们就会写入同一个文件中,减少加载文件的性能消耗
phpartisanoptimize--force
优化composer的自动加载
这不仅适用于laravel,而且适用于任何使用composer的应用程序。
我将首先解释PSR-4自动加载器的工作原理,然后向您展示应该运行什么命令来优化它。如果您对了解composer如何工作不感兴趣,我建议您直接跳到关于控制台命令的段落处。
当您向compsoser请求App\Controllers\AuthController类时,它首先在类映射中搜索直接关联。classmap是一个由类和文件组成的1到1关联的数组。当然,由于您没有手动将Login类及其相关文件添加到类映射中,composer将继续在命名空间中搜索。
因为App是一个PSR-4命名空间,默认情况下是与Laravel一起提供的,并且与app/文件夹相关联,所以composer将尝试使用基本的字符串操作过程将PSR-4类名转换为文件名。最后,它猜测App\Controllers\AuthController必须位于AuthController.php文件中,它位于Controllers/文件夹中,恰巧的是,该文件夹正好位于名称空间文件夹中,即app/。
所有这些艰苦的工作只是为了得到App\Controllers\AuthController类存在于app/Controllers/AuthController.php文件中。为了让composer扫描整个应用程序并创建类和文件的直接1对1关联,运行以下命令:
composerdumpautoload-o
请记住,如果您已经运行了phpartisanoptimize--force,那么您就不必再运行这个函数了。因为优化命令已经告诉composer创建一个优化的自动加载器。
JIT编译器(即时编译器)
PHP并不是天然就被计算机理解的。你不能把它编译为字节码然后让计算机运行。PHP必须要经过一个中介,像是Zend引擎,它会解释PHP文件并执行相应的C例程。如你所想,它的速度很慢。每次你的服务器执行一个PHP文件,都必须把它转换成tokens——这个过程由AST解析器完成并解释。不幸的是,解析器必须每次都编译PHP文件,即使它每次都得到相同的结果。
为了让你的应用速度更快,你需要一个编译一次,终生运行的方法,而这就是一个JIT编译器所做的事情。
对于Laravel所推荐使用的JIT编译器是HHVM,由Facebook创立并广泛使用。Wikipedia、Etsy和其他上千项目也在使用它。
使用更快的缓存和会话驱动
将session保存在文件中是种足够快速而又优雅的方法,自PHP开始的时代就在这样做了。但是如果你追求性能,那么文件系统就是你需要注意的一件事,因为它很慢。一种更好的做法是将cache和session存储在内存中,因为它提供了一种高效读写数据的方式。幸运的是,laravel支持一些基于内存的cache和session驱动。
我的建议是使用memcached作为cache和session的驱动,但你可以选择任何你喜欢的,只要它是基于内存工作的。
要更改session驱动,需要检查以下文件中「driver」项:
app/config/session.php
要更改cache驱动,需要检查以下文件中「driver」项:
app/config/cache.php
不要低估通过优化查询语句带来的查询速度的提升
就像你看到的,大部分优化都是在不同的层面使用缓存。但当面临数据库优化时,你不应该依赖缓存。缓存应是优化查询的最后手段。
缓存查询结果
MySQL不会替你做这件事,也不如你自己做的好。当然了你肯定不会把应用中每个查询的结果都做缓存,看看数据统计,在应用程序中那些高频率的查询语句,它们真的有必要被频繁地执行?每15分钟运行一次然后把相同的结果提供给用户不是更好吗?
在查询构造器中移除了removing方法是件好事(它曾经是个很好的功能,但不够好-人们似乎高估了它的作用)。然后你可以更多地使用Cache::remember方法,就像这样:
$posts=Cache::remember('index.posts',30,function() { returnPost::with('comments','tags','author','seo')->whereHidden(0)->get(); });