针对PHP7下安装Stone能提升Laravel框架性能!和phpstudy安装laravel框架这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展5分钟提高Laravel框架性能10倍以上、
针对PHP7下安装Stone能提升Laravel框架性能!和phpstudy安装laravel框架这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展5 分钟提高 Laravel 框架性能 10 倍以上、5分钟提高Laravel框架性能10倍以上、golang框架与Laravel框架的性能分析、golang框架性能提升实战等相关知识,希望可以帮助到你。
本文目录一览:- PHP7下安装Stone能提升Laravel框架性能!(phpstudy安装laravel框架)
- 5 分钟提高 Laravel 框架性能 10 倍以上
- 5分钟提高Laravel框架性能10倍以上
- golang框架与Laravel框架的性能分析
- golang框架性能提升实战
PHP7下安装Stone能提升Laravel框架性能!(phpstudy安装laravel框架)
下面由Laravel栏目给大家介绍在PHP7下安装Stone能提升Laravel框架性能的方法,希望对需要的朋友有所帮助!在PHP7下安装Stone大幅度提升Laravel框架性能
众所周知,PHP框架越重,性能相对就越低,因为重型框架会在解析时调用非常多的类、方法和自定义函数,导致性能严重下降。
Laravel是一个非常受欢迎的PHP框架,但它也是一个重型的全栈框架,你可以使用这个方法(https://xueyuanjun.com/post/2398.html)测试你的Laravel应用的性能,效果都很不理想。
当然Laravel还有个姊妹版:Lumen,这个是类似于Slim的微框架,如果你觉得这个微框架足够使用,可以用来替代Laravel。
好在PHP7相对于PHP5.6而言,性能提升了将近一倍,而Facebook的HHVM也是个不错的替代方案。所以如果可能的话,尽可能用最新版PHP,好处不是一星半点儿。
但对于Laravel这些重型框架来说,即使用了PHP7/HHVM,性能还是很低,虽然用缓存(比如memcached/redis等)可以缓解服务器压力,但只是提升了静态页面速度,对于Eloquent ORM这种很耗性能的地方,还是治标不治本(当然你可以用DB门面代替,参考我的这个提问),难道就没有办法了吗?(有人说opcache,但是它对于Laravel框架来说效果不是非常好)
不!你需要Stone!
Stone是什么?这是作者在PHPHub上面的帖子(https://learnku.com/laravel/t/2092/5-minutes-to-improve-the-performance-of-laravel-frame-more-than-10-times),查看Stone项目地址(https://github.com/StoneGroup/stone)和文档(https://chefxu.gitbooks.io/stone-docs/content/)。
下面是在PHP7的安装方法:
我的测试环境是Debian Linux 8 64位,OSX也可以(用homebrew安装Nginx和PHP7,其他操作见下面),不推荐用Windows,因为编译扩展相对麻烦些。
用Debian/Ubuntu/Linux mint可以使用dotdeb源,有最新版的Nginx,PHP7,MysqL/MariaDB。当然我不会告诉你,我用的是OpenResty,安装过程不赘述,不会的请Google。
首先安装swoole和runkit扩展。
pecl install swoole
PHP7在这里的坑是,如果用这个源安装了PHP7,由于PEAR不是最新版,可能会遇到这个issues描述的问题,解决方法:
wget http://pear.PHP.net/go-pear.phar PHP go-pear.phar
在撰写本文时,runkit扩展暂时不支持PHP7,所以不要用pecl安装,编译会出错的。但是有人做了修改版可以用,见这个issues。
安装方法:
git clone https://github.com/runkit7/runkit7.git cd runkit7 PHPize ./configure make sudo make install
到此这两个扩展都安装成功。
然后根据你的PHP7实际路径来写ini文件,加载swoole和runkit。至于Windows或者OSX用homebrew安装的话,直接改PHP.ini就行了。
使用Dotdeb源安装的PHP7路径是/etc/PHP/7.0/,所以我的相关命令是:
sudo echo extension=swoole.so >> /etc/PHP/7.0/cli/conf.d/20-swoole.ini sudo echo extension=swoole.so >> /etc/PHP/7.0/fpm/conf.d/20-swoole.ini sudo echo extension=runkit.so >> /etc/PHP/7.0/cli/conf.d/20-runkit.ini sudo echo extension=runkit.so >> /etc/PHP/7.0/fpm/conf.d/20-runkit.ini
然后安装Stone:composer require stone/kernel:dev-master,不得不说的是,在撰写本文时作者的gitbook上面有两个错误:
1.把pecl写成了pcel;
2.composer安装的地址。仍然是他之前的项目地址,而他在帖子里面说了,由于之前的项目包含了他的公司的某些信息,所以他换了个地址,就是StoneGroup/stone。
大家在参考Stone文档时务必按本文操作,少走弯路。我已向作者反馈,他修正了这个问题。
最后重启PHP-fpm,再用PHP -m看看,这两个扩展加载成功。
接下来的步骤,你按照文档来操作就行了,到此Stone在PHP7上面安装成功!启动Stone,好好享受性能的飞跃吧!
PS:找到另一个类似项目,但是在细节上面的实现方式不同,感兴趣的可以看看:https://github.com/scil/LaravelFly
5 分钟提高 Laravel 框架性能 10 倍以上
Stone 优化原理
快速入口:
- Stone 项目地址:https://github.com/chefxu/stone
- 一个 laravel5 的使用 stone 的例子
如果你正在考虑框架性能优化的问题, 你对 PHP 应该已经有足够的了解了。 如你所知, PHP 每次的每次请求结束, 都会释放掉执行中建立的所有资源。这样有一个很大的好处:PHP 程序员基本不用费力去考虑资源释放的问题,诸如内存,IO 句柄,数据库连接等,请求结束时 PHP 将全部释放。PHP 程序员几乎不用关心内存释放的问题,也很难写出内存泄露的程序。这让 PHP 变得更加简单容易上手, 直抒心意。但是也带来了一个坏处:PHP 很难在请求间复用资源, 类似 PHP 框架这种耗时的工作, 每次请求都需要反复做 —— 即使每次都在做同样的事情。也正因为如此,在 PHP 发展过程中,关于是否使用框架的争论也从未停止过。
Stone 主要优化的就是这个问题。 在框架资源初始化结束后再开启一个 FastCGI 服务,这样, 新的请求过来是直接从资源初始化结束后的状态开始,避免每次请求去做资源初始化的事情。所以, 本质上, Stone 运行时是常驻内存的,它和 PHP-FPM 一样,是一个 FastCGI 的实现,不同的是, FPM 每次执行请求都需要重新初始化框架, Stone 直接使用初始化的结果。
同样,事情总是有好有坏。坏处是:PHP 编程变得更难了, 你需要考虑内存的释放,需要关心 PHP 如何使用内存。甚至, 你需要了解使用的框架,以免『不小心』写出让人『惊喜』的效果。同时, PHP 的调试变得更难, 因为每次修改程序后需要重启进程才能看到效果。事实上开发 Stone 时针对这方面做了不少工作。好处是:程序的性能得到极大的提高。 当然, 客观上的一些利好因素是: PHP 的内存回收已经相当稳定和高效, Swoole 稳定性已经在相当多的项目中得到验证,Laravel 代码质量相当高。
在设计 Stone 时的另外一个目的是简单。 希望使用者能 5 分钟完成部署, 并且不需要对原有功能进行改造,可以安全地停止使用。
1. 关于 Stone-Web 和 Stone-Server
Stone 支持两种运行方式, Web 方式用来优化 Web 页面的执行, 执行流程和现在的 Laravel 页面完全一致。 Server 方式用来解决对性能要求很高的场合, 执行流程与 artisan command 一致, 绕过了 laravel MVC 的流程, 需要自己去实现请求处理的 Handler。
比如一个抢购活动, 想在用户实际下单前拦截请求避免对订单系统造成冲击, 可以使用 Stone-Server 实现一个抢购功能, 获得抢购资格的用户才进入下单流程。
2. 性能对比
应用类型 | 原始 Laravel | Stone-Web | Stone-Server |
---|---|---|---|
laravel5 默认页面 | 150 | 3000 | -- |
laravel5 简单接口 | 150 | 3000 | 8500 |
laravel4 实际项目简单页面 | 70 | 1000 | -- |
laravel4 简单接口 | 120 | -- | 8200 |
laravel4 实际项目首页 | 35 | 380 | -- |
测试环境如下:
PHP 5.6.17-0+deb8u1 (cli) (built: Jan 13 2016 09:10:12)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, by Zend Technologies
Linux office 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt20-1+deb8u3 (2016-01-17) x86_64 GNU/Linux
16核 Intel(R) Xeon(R) CPU E5-2640 v2 @ 2.00GHz
16G 内存
Laravel 4.2
Laravel 5.2
Stone 快速指南
注意:
- 如果你不能在 5 分钟内完成部署, 你应该停止使用 Stone 了 :)
- 目前 Stone 处在 alpha 阶段,本文档随时可能会失效
特别提示:
- 新项目中尝试 Stone, 建议从 Stone-Server 开始, 这是一个针对 API 的优化方案。
- 已有项目中尝试 Stone,建议从 Stone-Web 开始, 这是一个针对 Web 的优化方案。
- 请阅读一下风险提示
Stone 安装指引
安装 Stone
-
安装依赖包
sudo pcel install swoole sudo pcel install runkit
-
composer 安装 Stone
laravel 5:
composer require qufenqi/stone:dev-master
laravel 4:
composer require qufenqi/stone:dev-laravel-4.x
-
修改 config/app.php, 加载 Stone 的 Service Provider,
注意 Laravel4 的配置文件路径和写法有细微差别。
''providers'' => [ // laravel定义的provider Illuminate\Auth\AuthServiceProvider::class, Illuminate\Broadcasting\BroadcastServiceProvider::class, .... .... // 中间省略的其他provider .... Qufenqi\Stone\StoneServiceProvider::class, // 应用层定义的provider App\Providers\AppServiceProvider::class, App\Providers\AuthServiceProvider::class, App\Providers\EventServiceProvider::class, App\Providers\RouteServiceProvider::class, ],
-
配置 Stone: 新建 config/stone.php
注意 Laravel4 的配置文件路径有细微差别。
return [ // server模式配置 ''server'' => [ ''handler'' => ''App\Servers\Handler'', // request handler ''user'' => ''apple'', // run user ''group'' => ''apple'', // run group ''domain'' => ''/var/run/stone-server-fpm.sock'', ''pid'' => ''/run/stone-fpm.pid'', ''process_name'' => ''stone-server-fpm'', ''worker_num'' => 30, ], // web模式配置 ''web'' => [ ''user'' => ''apple'', // run user ''group'' => ''apple'', // run group ''domain'' => ''/var/run/stone-web-fpm.sock'', // unix domain socket ''pid'' => ''/run/stone-web.pid'', ''process_name'' => ''stone-web-server'', ''worker_num'' => 30, // 需要建立快照的绑定 ''snap_bindings'' => [ ''view'', ''cookie'', ''session'', ''session.store'', //''config'', // debugbar 需要重置config ], ], ];
在 Laravel 5 项目上使用 Stone-Web
-
修改 app/Http/Kernel.php, 让 Stone 的 Kernel 接管请求的处理。
// 根据当前的运行sapi决定使用哪个kernel来处理请求, 这样FPM和Stone可以完全使用一套程序 if (php_sapi_name() == ''cli'') { class BaseKernel extends StoneKernel {} } else { class BaseKernel extends HttpKernel {} } class Kernel extends BaseKernel
-
运行 Stone-Web, Web 模式处在开发阶段, 所以默认不会以 deamon 模式启动, 便于调试
sudo php ./public/index.php
-
修改 nginx 配置
location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_index index.php; # fastcgi_pass unix:/var/run/php5-fpm.sock; # PHP-FPM fastcgi_pass unix:/var/run/stone-web-fpm.sock; # Stone include fastcgi_params; }
sudo nginx -s reload
-
完成
在 Laravel 4 项目上使用 Stone-Web
-
修改 public/index.php 与 bootstrap/start.php, 让 Stone 的 Kernel 接管请求的处理。
// 修改public/index.php if (PHP_SAPI == ''cli'') { define(''STONE_WEB_MODE'', true); $_SERVER[''RUNENV''] = ''local''; }
// 修改bootstrap/start.php if (defined(''STONE_WEB_MODE'')) { $app = new Qufenqi\Stone\Foundation\Application; } else { $app = new Illuminate\Foundation\Application; }
-
运行 Stone-Web, Web 模式处在开发阶段, 所以默认不会以 deamon 模式启动, 便于调试
sudo php ./public/index.php
-
修改 nginx 配置
location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_index index.php; # fastcgi_pass unix:/var/run/php5-fpm.sock; # PHP-FPM fastcgi_pass unix:/var/run/stone-web-fpm.sock; # Stone include fastcgi_params; }
sudo nginx -s reload
-
完成
在 Laravel 5 中使用 Stone-Server
-
修改 app\Console\Kernel.php
protected $commands = [ // Commands\Inspire::class, \Qufenqi\Stone\Console\Commands\StoneServer::class, // 添加这一行 ];
-
定义请求处理类, 我定义在 app\Servers\Handler.php
注意 这个其实就是 stone.php 配置里的 server.handler
<?php namespace App\Servers; use Qufenqi\Stone\Contracts\RequestHandler; use Response; class Handler implements RequestHandler { public function process() { return Response::make(''hello, stone server!''); } public function onWorkerStart() { } }
-
运行 Stone-Server
sudo php ./artisan stone:server
-
修改 nginx 配置
location /server/ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_index index.php; fastcgi_pass unix:/var/run/stone-server-fpm.sock; # Stone include fastcgi_params; }
sudo nginx -s reload
-
完成
在 Laravel 4 中使用 Stone-Server
-
修改 app\start\artisan.php
Artisan::add(new Qufenqi\Stone\Console\Commands\StoneServer);
-
定义请求处理类, 我定义在 app\Servers\Handler.php
注意 这个其实就是 stone.php 配置里的 server.handler
<?php namespace App\Servers; use Qufenqi\Stone\Contracts\RequestHandler; use Response; class Handler implements RequestHandler { public function process() { return Response::make(''hello, stone server!''); } public function onWorkerStart() { } }
-
运行 Stone-Server
sudo php ./artisan stone:server
-
修改 nginx 配置
location /server/ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_index index.php; fastcgi_pass unix:/var/run/stone-server-fpm.sock; # Stone include fastcgi_params; }
sudo nginx -s reload
-
完成
Stone 进阶指南
1. Stone 的使用风险
使用 Stone 的一个很重要的事情是, 需要始终对内存使用抱有敬畏之心。 在未充分了解风险前, 请不要在实际项目中轻易尝试,否则可能产生非常严重的后果!!
比如:Laravle 的 Cookie 实现了单例模式, 是为了让开发者在任何地方可以往 Response 里追加 cookie, 使用:
Cookie::queue(''key'', ''value'', 60);
这在 PHP-FPM 下不会有任何问题。 但 Stone 常驻内存后, 请求的资源没有在请求结束后释放, 因此上一个请求在 Cookie 在下一个请求中仍然存在。 想像下, 如果这是一个关于 Session Id 的 cookie, 会产生多么严重的后果。 同样,Laravel 的 Auth 对象, 也可能出现类似的问题。
内存泄露什么的可能只是影响稳定性, 但是这个处理不当会带来难以估计的损失, 这是使用 Stone 或者类似常驻内存方案的最大风险。
2. Boot Service Provider 与 Request Service Provider
使用 Stone(或者使用类似常驻内存解决方案)最重要的一点, 是需要区分哪些资源可以请求间共享, 哪些资源不能共享。这在 Stone 中被区别为: boot service provider 和 request service provider。
- boot service provider 在进程初始化时被执行, 请求间共享。
- request service provider 在请求时执行, 请求间不共享,每次请求重新执行。
- laravel 原来定义的 service provider 默认都是 boot service Provider, 除非你在 stone 配置里重新定义。
比如, Laravel 的路由规则的解析, 是不需要每次请求都去执行的,而在一个时间较长的项目中, 路由规则可能有几千行,解析这些规则需要耗费不少时间, 所以设置成 boot service provider 是比较合适的。 而有一些 service provider 是需要每次都执行的,比如 debugbar, 这些设置成 request service provider 比较合适。
3. 实例快照与 runkit
还有一种情况,不需要每次执行具体的代码, 但是需要做一些重置操作。 比如 Cookie, Laravel 将 cookie 放到 Response 的数组中, 在结束响应时发送到浏览器端,请求结束后并没有清空而带到了下一个请求。 Stone 的一个解决办法是将 Cookie 在创建时建立一个快照, 保存当前的状态, 等请求结束时再通过快照恢复, 避免 Cookie 被带到下一个请求的问题。
这个在 config/stone.php 里可以定义。
runkit 在这个过程中的意义是给予 PHP 运行时注入实例的能力。 在 app 初始化时通过 runkit 注入指定实例, 让他们具有快照恢复的功能, 再建立快照, 请求结束后再通过快照恢复。
快照和 request service provider 都能解决 Cookie 在请求间共享的问题, 快照的方式避免了再次执行 service provider 里 register 和 boot 的工作, 效率会更好一些。 如果你只是需要每次请求得到一个新的实例, 而不是需要在请求中再次执行一段程序, 使用快照的方式会更好一些。
4. 理解请求间共享资源
这是一把双刃剑, 利用好了性能能得到极大提升, 否则就是 bug 的深渊。
比如, 我们常需要实现权限系统, 如果能在初始化的时候将权限系统加载, 并在请求间共享, 这样每次请求就不需要再去从数据库里加载解析权限规则, 这样效率能得到提高。 利用好了这一点, 有助于你写出更高效的程序。
而如果你没理解好这一点, 比如你使用了一个单例模式, 这个实例被维持在类的静态变量里, 因此不会在请求结束后自然销毁。 而这个实例在请求间共享又会出现问题,类似 cookie 的问题,这样就会造成 bug。
5. 沙盒模式
我希望在未来能支持沙盒模式, 在初始化后建立一个沙盒, 把请求防止到沙盒里执行, 这样就可以更安全方便的实现。
设计 Stone 的一些想法
1. 保持与 PHP-FPM 的兼容
这样做能带来几个好处:
- 调试方便, 在开发中, 程序员完全可以使用 php-fpm 来开发, 这样可以避免开发时反复重启进程的问题。 当然, 测试时还是应该使用 Stone,免得一些问题需要在线上时才发现。
- 使用方便, 5 分钟内快速使用这个目标不会改变
- 停用方便, 出现一些暂时无法解决的问题的时候, 可以通过修改 nginx 配置快速切换会 PHP-FPM
2. 什么场合下适合使用 Stone
Stone 的目标定位于解决已有 PHP 程序的性能问题。 随着开源程序的越来越完善, 现在解决高并发问题的技术方案越来越多, 有些已经非常成熟。 Stone 的优势在于在解决性能问题的同时可以 100% 重用现在的业务逻辑。
比如, 现有系统中需要加入一个抢购的功能, 我们可能会在抢购之前根据业务规则进行流量拦截, 可能需要使用到 redis, 现有的用户系统,现有的业务规则。 使用 Stone-Server, 你可以直接使用。 但是如果你使用其他语言的解决方案, 你可能需要把这些规则使用另外的语言再实现一遍。 这加大了开发和维护的成本。
3. 继续降低使用 Stone 的难度
使用 Stone 很可能会踩坑。 一方面可能是开发者对于运行机制的理解不充分; 一方面可能是现有 PHP 程序没有考虑请求结束后的资源销毁的问题; 也可能是 Stone 本身程序存在一些 bug。 Stone 会持续完善, 并尽量对应用程序提供一些保护机制, 降低程序使用的难度。
在其他框架下使用 Stone
由于精力有限, 暂时不考虑其他框架, 但是应该是可以较快移至到其他框架的。 如果你有兴趣, 不妨 fork 代码自己实现一下。
问题反馈
希望感兴趣的朋友能积极给我反馈, 甚至参与到 Stone 的开发中来, 我们一起完善。 我的邮箱是: rssidea (at) qq.com
5分钟提高Laravel框架性能10倍以上
Stone优化原理
快速入口:
- Stone项目地址:https://github.com/chefxu/stone
- 一个laravel5的使用stone的例子
如果你正在考虑框架性能优化的问题, 你对PHP应该已经有足够的了解了。 如你所知, PHP每次的每次请求结束, 都会释放掉执行中建立的所有资源。这样有一个很大的好处:PHP程序员基本不用费力去考虑资源释放的问题,诸如内存,IO句柄,数据库连接等,请求结束时PHP将全部释放。PHP程序员几乎不用关心内存释放的问题,也很难写出内存泄露的程序。这让PHP变得更加简单容易上手, 直抒心意。但是也带来了一个坏处:PHP很难在请求间复用资源, 类似PHP框架这种耗时的工作, 每次请求都需要反复做——即使每次都在做同样的事情。也正因为如此,在PHP发展过程中,关于是否使用框架的争论也从未停止过。
Stone主要优化的就是这个问题。 在框架资源初始化结束后再开启一个FastCGI服务,这样, 新的请求过来是直接从资源初始化结束后的状态开始,避免每次请求去做资源初始化的事情。所以, 本质上, Stone运行时是常驻内存的,它和PHP-FPM一样,是一个FastCGI的实现,不同的是, FPM每次执行请求都需要重新初始化框架, Stone直接使用初始化的结果。
同样,事情总是有好有坏。坏处是:PHP编程变得更难了, 你需要考虑内存的释放,需要关心PHP如何使用内存。甚至, 你需要了解使用的框架,以免『不小心』写出让人『惊喜』的效果。同时, PHP的调试变得更难, 因为每次修改程序后需要重启进程才能看到效果。事实上开发Stone时针对这方面做了不少工作。好处是:程序的性能得到极大的提高。 当然, 客观上的一些利好因素是: PHP的内存回收已经相当稳定和高效, Swoole稳定性已经在相当多的项目中得到验证,Laravel代码质量相当高。
在设计Stone时的另外一个目的是简单。 希望使用者能5分钟完成部署, 并且不需要对原有功能进行改造,可以安全地停止使用。
1. 关于 Stone-Web 和 Stone-Server
Stone支持两种运行方式, Web方式用来优化Web页面的执行, 执行流程和现在的Laravel页面完全一致。 Server方式用来解决对性能要求很高的场合, 执行流程与artisan command一致, 绕过了laravel MVC的流程, 需要自己去实现请求处理的Handler。
比如一个抢购活动, 想在用户实际下单前拦截请求避免对订单系统造成冲击, 可以使用Stone-Server实现一个抢购功能, 获得抢购资格的用户才进入下单流程。
2. 性能对比
应用类型 | 原始Laravel | Stone-Web | Stone-Server |
---|---|---|---|
laravel5 默认页面 | 150 | 3000 | -- |
laravel5 简单接口 | 150 | 3000 | 8500 |
laravel4 实际项目简单页面 | 70 | 1000 | -- |
laravel4 简单接口 | 120 | -- | 8200 |
laravel4 实际项目首页 | 35 | 380 | -- |
测试环境如下:
PHP 5.6.17-0+deb8u1 (cli) (built: Jan 13 2016 09:10:12)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, by Zend Technologies
Linux office 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt20-1+deb8u3 (2016-01-17) x86_64 GNU/Linux
16核 Intel(R) Xeon(R) CPU E5-2640 v2 @ 2.00GHz
16G 内存
Laravel 4.2
Laravel 5.2
Stone快速指南
注意:
- 如果你不能在5分钟内完成部署, 你应该停止使用Stone了 :)
- 目前Stone处在alpha阶段,本文档随时可能会失效
特别提示:
- 新项目中尝试Stone, 建议从Stone-Server开始, 这是一个针对API的优化方案。
- 已有项目中尝试Stone,建议从Stone-Web开始, 这是一个针对Web的优化方案。
- 请阅读一下风险提示
Stone安装指引
安装Stone
-
安装依赖包
sudo pcel install swoole sudo pcel install runkit
-
composer安装Stone
laravel 5:
composer require qufenqi/stone:dev-master
laravel 4:
composer require qufenqi/stone:dev-laravel-4.x
-
修改config/app.php, 加载Stone的Service Provider,
注意Laravel4的配置文件路径和写法有细微差别。
''providers'' => [ // laravel定义的provider Illuminate\Auth\AuthServiceProvider::class, Illuminate\Broadcasting\BroadcastServiceProvider::class, .... .... // 中间省略的其他provider .... Qufenqi\Stone\StoneServiceProvider::class, // 应用层定义的provider App\Providers\AppServiceProvider::class, App\Providers\AuthServiceProvider::class, App\Providers\EventServiceProvider::class, App\Providers\RouteServiceProvider::class, ],
-
配置Stone: 新建 config/stone.php
注意Laravel4的配置文件路径有细微差别。
return [ // server模式配置 ''server'' => [ ''handler'' => ''App\Servers\Handler'', // request handler ''user'' => ''apple'', // run user ''group'' => ''apple'', // run group ''domain'' => ''/var/run/stone-server-fpm.sock'', ''pid'' => ''/run/stone-fpm.pid'', ''process_name'' => ''stone-server-fpm'', ''worker_num'' => 30, ], // web模式配置 ''web'' => [ ''user'' => ''apple'', // run user ''group'' => ''apple'', // run group ''domain'' => ''/var/run/stone-web-fpm.sock'', // unix domain socket ''pid'' => ''/run/stone-web.pid'', ''process_name'' => ''stone-web-server'', ''worker_num'' => 30, // 需要建立快照的绑定 ''snap_bindings'' => [ ''view'', ''cookie'', ''session'', ''session.store'', //''config'', // debugbar 需要重置config ], ], ];
在Laravel 5 项目上使用Stone-Web
-
修改app/Http/Kernel.php, 让Stone的Kernel接管请求的处理。
// 根据当前的运行sapi决定使用哪个kernel来处理请求, 这样FPM和Stone可以完全使用一套程序 if (php_sapi_name() == ''cli'') { class BaseKernel extends StoneKernel {} } else { class BaseKernel extends HttpKernel {} } class Kernel extends BaseKernel
-
运行Stone-Web, Web模式处在开发阶段, 所以默认不会以deamon模式启动, 便于调试
sudo php ./public/index.php
-
修改nginx配置
location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_index index.php; # fastcgi_pass unix:/var/run/php5-fpm.sock; # PHP-FPM fastcgi_pass unix:/var/run/stone-web-fpm.sock; # Stone include fastcgi_params; }
sudo nginx -s reload
-
完成
在Laravel 4 项目上使用Stone-Web
-
修改public/index.php与bootstrap/start.php, 让Stone的Kernel接管请求的处理。
// 修改public/index.php if (PHP_SAPI == ''cli'') { define(''STONE_WEB_MODE'', true); $_SERVER[''RUNENV''] = ''local''; }
// 修改bootstrap/start.php if (defined(''STONE_WEB_MODE'')) { $app = new Qufenqi\Stone\Foundation\Application; } else { $app = new Illuminate\Foundation\Application; }
-
运行Stone-Web, Web模式处在开发阶段, 所以默认不会以deamon模式启动, 便于调试
sudo php ./public/index.php
-
修改nginx配置
location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_index index.php; # fastcgi_pass unix:/var/run/php5-fpm.sock; # PHP-FPM fastcgi_pass unix:/var/run/stone-web-fpm.sock; # Stone include fastcgi_params; }
sudo nginx -s reload
-
完成
在Laravel 5 中使用Stone-Server
-
修改app\Console\Kernel.php
protected $commands = [ // Commands\Inspire::class, \Qufenqi\Stone\Console\Commands\StoneServer::class, // 添加这一行 ];
-
定义请求处理类, 我定义在app\Servers\Handler.php
注意 这个其实就是 stone.php 配置里的 server.handler
<?php namespace App\Servers; use Qufenqi\Stone\Contracts\RequestHandler; use Response; class Handler implements RequestHandler { public function process() { return Response::make(''hello, stone server!''); } public function onWorkerStart() { } }
-
运行Stone-Server
sudo php ./artisan stone:server
-
修改nginx配置
location /server/ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_index index.php; fastcgi_pass unix:/var/run/stone-server-fpm.sock; # Stone include fastcgi_params; }
sudo nginx -s reload
-
完成
在Laravel 4 中使用Stone-Server
-
修改app\start\artisan.php
Artisan::add(new Qufenqi\Stone\Console\Commands\StoneServer);
-
定义请求处理类, 我定义在app\Servers\Handler.php
注意 这个其实就是 stone.php 配置里的 server.handler
<?php namespace App\Servers; use Qufenqi\Stone\Contracts\RequestHandler; use Response; class Handler implements RequestHandler { public function process() { return Response::make(''hello, stone server!''); } public function onWorkerStart() { } }
-
运行Stone-Server
sudo php ./artisan stone:server
-
修改nginx配置
location /server/ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_index index.php; fastcgi_pass unix:/var/run/stone-server-fpm.sock; # Stone include fastcgi_params; }
sudo nginx -s reload
-
完成
Stone进阶指南
1. Stone的使用风险
使用Stone的一个很重要的事情是, 需要始终对内存使用抱有敬畏之心。 在未充分了解风险前, 请不要在实际项目中轻易尝试,否则可能产生非常严重的后果!!
比如:Laravle的Cookie实现了单例模式, 是为了让开发者在任何地方可以往Response里追加cookie, 使用:
Cookie::queue(''key'', ''value'', 60);
这在PHP-FPM下不会有任何问题。 但Stone常驻内存后, 请求的资源没有在请求结束后释放, 因此上一个请求在Cookie在下一个请求中仍然存在。 想像下, 如果这是一个关于Session Id的cookie, 会产生多么严重的后果。 同样,Laravel的Auth对象, 也可能出现类似的问题。
内存泄露什么的可能只是影响稳定性, 但是这个处理不当会带来难以估计的损失, 这是使用Stone或者类似常驻内存方案的最大风险。
2. Boot Service Provider 与 Request Service Provider
使用Stone(或者使用类似常驻内存解决方案)最重要的一点, 是需要区分哪些资源可以请求间共享, 哪些资源不能共享。这在 Stone中被区别为: boot service provider 和 request service provider。
- boot service provider在进程初始化时被执行, 请求间共享。
- request service provider在请求时执行, 请求间不共享, 每次请求重新执行。
- laravel原来定义的service provider默认都是boot service Provider, 除非你在stone配置里重新定义。
比如, Laravel的路由规则的解析, 是不需要每次请求都去执行的,而在一个时间较长的项目中, 路由规则可能有几千行,解析这些规则需要耗费不少时间, 所以设置成boot service provider是比较合适的。 而有一些service provider是需要每次都执行的,比如debugbar, 这些设置成request service provider比较合适。
3. 实例快照与runkit
还有一种情况,不需要每次执行具体的代码, 但是需要做一些重置操作。 比如Cookie, Laravel将cookie放到Response的数组中, 在结束响应时发送到浏览器端,请求结束后并没有清空而带到了下一个请求。 Stone的一个解决办法是将Cookie在创建时建立一个快照, 保存当前的状态, 等请求结束时再通过快照恢复, 避免Cookie被带到下一个请求的问题。
这个在config/stone.php里可以定义。
runkit在这个过程中的意义是给予PHP运行时注入实例的能力。 在app初始化时通过runkit注入指定实例, 让他们具有快照恢复的功能, 再建立快照, 请求结束后再通过快照恢复。
快照和request service provider都能解决Cookie在请求间共享的问题, 快照的方式避免了再次执行service provider里register和boot的工作, 效率会更好一些。 如果你只是需要每次请求得到一个新的实例, 而不是需要在请求中再次执行一段程序, 使用快照的方式会更好一些。
4. 理解请求间共享资源
这是一把双刃剑, 利用好了性能能得到极大提升, 否则就是bug的深渊。
比如, 我们常需要实现权限系统, 如果能在初始化的时候将权限系统加载, 并在请求间共享, 这样每次请求就不需要再去从数据库里加载解析权限规则, 这样效率能得到提高。 利用好了这一点, 有助于你写出更高效的程序。
而如果你没理解好这一点, 比如你使用了一个单例模式, 这个实例被维持在类的静态变量里, 因此不会在请求结束后自然销毁。 而这个实例在请求间共享又会出现问题,类似cookie的问题,这样就会造成bug。
5. 沙盒模式
我希望在未来能支持沙盒模式, 在初始化后建立一个沙盒, 把请求防止到沙盒里执行, 这样就可以更安全方便的实现。
设计Stone的一些想法
1. 保持与PHP-FPM的兼容
这样做能带来几个好处:
- 调试方便, 在开发中, 程序员完全可以使用php-fpm来开发, 这样可以避免开发时反复重启进程的问题。 当然, 测试时还是应该使用Stone,免得一些问题需要在线上时才发现。
- 使用方便, 5分钟内快速使用这个目标不会改变
- 停用方便, 出现一些暂时无法解决的问题的时候, 可以通过修改nginx配置快速切换会PHP-FPM
2. 什么场合下适合使用Stone
Stone的目标定位于解决已有PHP程序的性能问题。 随着开源程序的越来越完善, 现在解决高并发问题的技术方案越来越多, 有些已经非常成熟。 Stone的优势在于在解决性能问题的同时可以100%重用现在的业务逻辑。
比如, 现有系统中需要加入一个抢购的功能, 我们可能会在抢购之前根据业务规则进行流量拦截, 可能需要使用到redis, 现有的用户系统,现有的业务规则。 使用Stone-Server, 你可以直接使用。 但是如果你使用其他语言的解决方案, 你可能需要把这些规则使用另外的语言再实现一遍。 这加大了开发和维护的成本。
3. 继续降低使用Stone的难度
使用Stone很可能会踩坑。 一方面可能是开发者对于运行机制的理解不充分; 一方面可能是现有PHP程序没有考虑请求结束后的资源销毁的问题; 也可能是Stone本身程序存在一些bug。 Stone会持续完善, 并尽量对应用程序提供一些保护机制, 降低程序使用的难度。
在其他框架下使用Stone
由于精力有限, 暂时不考虑其他框架, 但是应该是可以较快移至到其他框架的。 如果你有兴趣, 不妨fork代码自己实现一下。
问题反馈
希望感兴趣的朋友能积极给我反馈, 甚至参与到Stone的开发中来, 我们一起完善。 我的邮箱是: rssidea(at)qq.com
golang框架与Laravel框架的性能分析
Golang 与 Laravel 框架的性能分析
简介
Golang 和 Laravel 是两种流行的 Web 开发框架,它们以不同的方式提供高性能。本文将对这两种框架进行性能分析,帮助开发人员做出明智的选择。
立即学习“go语言免费学习笔记(深入)”;
基准测试
为了比较 Golang 和 Laravel 的性能,我们进行了一系列基准测试。基准测试在 Amazon EC2 实例(t3.medium)上执行,具有 2 个 vCPU 和 4 GB RAM。
端点调用
我们测试了每个框架对简单端点的响应时间。结果如下:
框架 | 平均响应时间(毫秒) |
---|---|
Golang | 5.2 |
Laravel | 12.6 |
数据库查询
我们还测试了每个框架执行数据库查询的速度。结果如下:
框架 | 平均查询时间(毫秒) |
---|---|
Golang | 1.8 |
Laravel | 4.5 |
优点和缺点
-
Golang
- 高并发性
- 低内存开销
- 编译型语言,性能优异
-
Laravel
- 基于队列的多进程架构
- 易于使用的 Eloquent ORM
- 丰富的生态系统
实战案例
为了展示 Golang 和 Laravel 的实际性能,我们开发了两个简单的 Web 应用程序:
- 电子商务商店(包含购物篮、产品目录和订单处理)
-
博客系统(包含文章、类别和评论)
结果
以并发用户为指标,我们比较了两个应用程序的性能。结果表明,Golang 应用程序在高并发情况下表现得更好。
结论
Golang 和 Laravel 都提供了高性能的 Web 开发解决方案。然而,对于高并发 Web 应用程序,Golang 凭借其固有的高并发性和低开销优势脱颖而出。对于具有强大 ORM 和丰富生态系统的应用程序,Laravel 仍然是一个不错的选择。
以上就是
golang框架性能提升实战
go 框架的性能提升可通过优化代码,例如避免不必要的内存分配、减少锁竞争和优化 i/o 操作。具体技巧包括使用内存池、减少分配次数、使用无锁数据结构、优化锁粒度、使用缓存、批量处理和非阻塞 i/o。实战案例涉及优化 http 服务器性能(减少锁竞争、内存分配和使用非阻塞 i/o),以及优化数据库查询性能(缓存常用查询和使用批量处理)。通过遵循这些技巧,可以显著提升 go 框架的性能,满足高并发和低延迟的要求。
Go 框架性能提升实战
简介
Go 是一种以高性能著称的语言。然而,在某些场景下,Go 框架的性能可能会受到一些因素的影响,如内存分配、锁竞争和 I/O 瓶颈。本文将介绍一些实用技巧,帮助你提升 Go 框架的性能。
立即学习“go语言免费学习笔记(深入)”;
代码优化技巧
- 避免不必要的内存分配:Go 中频繁的内存分配会增加 GC 压力,降低性能。使用内存池或减少分配次数可以缓解这个问题。例如:
var buffer bytes.Buffer func WriteString(s string) { buffer.Reset() buffer.WriteString(s) }
- 减少锁竞争:锁的争用会严重影响并行性能。可以考虑使用无锁数据结构或优化锁粒度来减少竞争。例如,使用通道同步比使用互斥锁更高效:
var channel = make(chan bool) func SomeFunction() { channel <- true }
- 优化 I/O 操作:I/O 操作可能是性能瓶颈。可以使用缓存、批量处理和非阻塞 I/O 来提高效率。例如:
import "io/ioutil" func ReadFile(filename string) []byte { return ioutil.ReadFile(filename) }
实战案例
优化 HTTP 服务器性能:
// 减少锁竞争 mux.Lock() defer mux.Unlock() // 减少内存分配 var requestHandler = http.DefaultServeMux.ServeHTTP // 使用非阻塞 I/O http.ListenAndServe("localhost:8080", nil)
优化数据库查询性能:
// 缓存常用查询 rows, err := db.Query("SELECT * FROM users") // 使用批量处理 for rows.Next() { var user User err := rows.Scan(&user.ID, &user.Name) if err != nil { return err } users[user.ID] = user }
结论
通过遵循这些技巧,你可以显著提升 Go 框架的性能,满足高并发和低延迟的要求。持续监测和分析性能指标,并在需要时进行调整,可以确保你的系统始终保持最佳状态。
以上就是
今天关于PHP7下安装Stone能提升Laravel框架性能!和phpstudy安装laravel框架的讲解已经结束,谢谢您的阅读,如果想了解更多关于5 分钟提高 Laravel 框架性能 10 倍以上、5分钟提高Laravel框架性能10倍以上、golang框架与Laravel框架的性能分析、golang框架性能提升实战的相关知识,请在本站搜索。
本文标签: