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 协议》,转载必须注明作者和本文链接
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。