LaravelConf 2018《优雅与效能,Laravel 与 swoole 整合之路》笔记

在线视频

  1. 地址1:www.youtube.com/watch?v=wTrUOWuJBl...
  2. 地址2:www.pilishen.com/casts/speed-up-la...

laravel为什么慢

  1. 一次请求差不多要加载200多个php,当然也可以用opcache
  2. 每次请求结束,所有资源都被销毁,不能重复利用。下面有一个laravel的请求生命周期图:

和swoole整合的方案

方案1

把swoole当php-fpm一样使用,每次处理请求都加载一下laravel核心,其实还是不能避免每次都加载200多个php,代码如下:

public function onRequest($swooleRequest, $swooleResponse) {
    $app = require_once __DIR__.'/bootstrap/app.php';
    $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
    $illuminateRequest = Request::make($swooleRequest)->toIlluminate();
    $illuminateResponse = $kernel->handle($illuminateRequest);
    $response->end($illuminateResponse->getContent());
    $kernel->terminate($illuminateRequest, $illuminateResponse);
}

方案2

公用一个laravel容器,代码如下:

public function onRequest($swooleRequest, $swooleResponse) {
    $app = $this->getApplication();
    $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
    $illuminateRequest = Request::make($swooleRequest)->toIlluminate();
    $illuminateResponse = $kernel->handle($illuminateRequest);
    $response->end($illuminateResponse->getContent());
    $kernel->terminate($illuminateRequest, $illuminateResponse);
}

这个方案对比方案1,可以不用重复加载php了,laravel的请求生命周期图如下:

这个方案的问题是如果A用户登录了,B用户访问swoole同一个worker的时候也是登录状态,因为AuthManager是单例,同一个进程是数据共享的。实际上,单例、全局变量、静态属性也都是数据共享的。这样就造成数据安全问题了。

方案3

基于方案2,每次获取容器实例后,清理掉单例对象,理论上可行,但是太繁琐了

方案4

基于方案2,第一次laravel容器初始化并注册服务提供者和实例后,就克隆一个干净的对象sandBox。每次请求都基于sandBox做后续的处理,sandBox每次都会reset一下。
这个方案的laravel的请求生命周期图如下:

此方案的GitHub地址是:github.com/swooletw/laravel-swoole

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 1
happyqian_ah

好文章,赞一下。

4年前 评论

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