線上視訊
laravel為什麼慢
- 一次請求差不多要載入200多個php,當然也可以用opcache
- 每次請求結束,所有資源都被銷燬,不能重複利用。下面有一個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 協議》,轉載必須註明作者和本文連結