Laravel 應用性能調優

 

1). 調優

Laravel 中的一下調優和測試方式php

 

2). 方式

此次性能測試方案中用到的優化技巧主要基於 Laravel 框架自己及其提供的工具。前端

  1. 關閉應用debug app.debug=falselaravel

  2. 緩存配置信息 php artisan config:cache數據庫

  3. 緩存路由信息 php artisan router:cachejson

  4. 類映射加載優化 php artisan optimizebootstrap

  5. 自動加載優化 composer dumpautoload瀏覽器

  6. 根據須要只加載必要的中間件緩存

  7. 使用即時編譯器(JIT),如:HHVM、OPcache服務器

  8. 使用 PHP 7.xsession

除了以上優化技巧以外,還有不少編碼上的實踐能夠提高 Laravel 應用性能,在本文中暫時不會作說明。(也能夠關注個人後續文章)

1. 關閉應用 debug

打開應用根目錄下的 .env 文件,把 debug 設置爲 false。

APP_DEBUG=false

2. 緩存配置信息

php artisan config:cache

運行以上命令能夠把 config 文件夾裏全部配置信息合併到一個 bootstrap/cache/config.php 文件中,減小運行時載入文件的數量。

php artisan config:clear

運行以上命令能夠清除配置信息的緩存,也就是刪除 bootstrap/cache/config.php 文件

3. 緩存路由信息

php artisan route:cache

運行以上命令會生成文件 bootstrap/cache/routes.php。路由緩存能夠有效的提升路由器的註冊效率,在大型應用程序中效果越加明顯。

php artisan route:clear

運行以上命令會清除路由緩存,也就是刪除 bootstrap/cache/routes.php 文件。

4. 類映射加載優化

php artisan optimize --force

運行以上命令可以把經常使用加載的類合併到一個文件中,經過減小文件的加載來提升運行效率。這個命令會生成 bootstrap/cache/compiled.php 和 bootstrap/cache/services.json兩個文件。

經過修改 config/compile.php 文件能夠添加要合併的類。

在生產環境中不須要指定 --force 參數文件也能夠自動生成。

php artisan clear-compiled

運行以上命令會清除類映射加載優化,也就是刪除 bootstrap/cache/compiled.php 和 bootstrap/cache/services.json 兩個文件。

5. 自動加載優化

composer dumpautoload -o

Laravel 應用程序是使用 composer 來構建的。這個命令會把 PSR-0 和 PSR-4 轉換爲一個類映射表來提升類的加載速度。

注意:php artisan optimize --force 命令裏已經作了這個操做。

6. 根據須要只加載必要的中間件

Laravel 應用程序內置了並開啓了不少的中間件。每個 Laravel 的請求都會加載相關的中間件、產生各類數據。在 app/Http/Kernel.php 中註釋掉不須要的中間件(如 session 支持)能夠極大的提高性能。

7. 使用即時編譯器

HHVM 和 OPcache 都能輕輕鬆鬆的讓你的應用程序在不用作任何修改的狀況下,直接提升 50% 或者更高的性能。

8. 使用 PHP 7.x

只能說 PHP 7.x 比起以前的版本在性能上有了極大的提高。

嗯,限於你的真實企業環境,這個也許很長時間內改變不了,算我沒說。

3) 測試方案

咱們使用簡單的 Apache ab 命令僅對應用入口文件進行測試,並記錄和分析數據。

  1. 僅對應用的入口文件 index.php 進行測試,訪問 「/」 或者 「/index.php」 返回框架的歡迎頁面。更全面的性能測試須要針對應用的更多接口進行測試。

  2. 使用 Apache ab 命令。ab -t 10 -c 10 {url}。該命令表示對 url 同時發起 10 個請求,並持續 10 秒鐘。命令中具體的參數設置須要根據要測試的服務器性能進行選擇。

  3. 爲了不機器波動致使的數據錯誤,每種測試條件會執行屢次 ab 命令,並記錄命令執行結果,重點關注每秒處理的請求數及請求響應時間,分析並剔除異常值。

  4. 每次對測試條件進行了調整,須要在瀏覽器上對歡迎頁進行訪問,確保沒有由於測試條件修改而訪問出錯。若是頁面訪問出錯會致使測試結果錯誤。

服務器環境說明

全部脫離具體環境的測試數據都沒有意義,而且只有在相近的條件下才能夠進行比較。

  1. 這套環境運行在 Mac 上,內存 8G,處理器 2.8GHz,SSD 硬盤。

  2. 測試服務器是使用 Homestead 搭建的。虛擬機配置爲單核 CPU、2G 內存。

  3. 服務器 PHP 版本爲 7.1,未特殊說明,則標識開啓了 OPcache。

  4. 測試的 Laravel 應用程序採用 5.2 版本編寫。app\Http\routes.php 中定義了 85 個路由。

  5. 測試過程當中除了虛擬機、終端及固定的瀏覽器窗口外,沒有會影響機器的程序運行。

以上的數據,你們在本身進行測試時能夠參考。

4). 測試過程及數據

1. 未作任何優化

 

1.1 操做

 

  • 按照如下檢查項執行相應的操做。

  • 運行 ab -t 10 -c http://myurl.com/index.php

基礎檢查項

  • .env 文件中 APP_DEBUG=true

  • 不存在 bootstrap/cache/config.php

  • 不存在 bootstrap/cache/routes.php

  • 不存在 bootstrap/cache/compiled.php 和 bootstrap/cache/services.json

  • app/Http/Kernel.php 中開啓了大部分的中間件

  • 瀏覽器訪問 Laravel 應用程序歡迎頁確保正常訪問

 

1.2 數據記錄

2. 關閉應用debug

 

2.1 操做

 

  • 在步驟 1 基礎上修改 .env 文件中 APP_DEBUG=false

  • 瀏覽器訪問 Laravel 應用程序歡迎頁確保正常訪問。

  • 運行 ab -t 10 -c http://myurl.com/index.php

 

2.2 數據記錄

2.3 對比結果

與步驟 1 結果比較發現:關閉應用 debug 以後,每秒處理請求數從 26-34 上升到 33-35,請求響應時間從 大部分 300ms 以上降低到 290ms 左右,效果不太明顯,但確實有必定的提高。

注意:這部分與應用中的日誌等使用狀況有比較大的關聯。

3. 開啓緩存配置信息

 

3.1 操做

 

  • 在步驟 2 基礎上,運行 php artisan config:cache,確認生成bootstrap/cache/config.php

  • 瀏覽器訪問 Laravel 應用程序歡迎頁確保正常訪問。

  • 運行 ab -t 10 -c http://myurl.com/index.php

 

3.2 數據記錄

3.3 對比結果

與步驟 2 結果比較發現:開啓配置信息緩存以後,每秒處理請求數從 33-35 上升到 36-38,請求響應時間從 290ms 左右降低到 260ms 左右,效果不太明顯,但確實有必定的提高。

4. 開啓緩存路由信息

 

4.1 操做

 

  • 在步驟 3 基礎上,運行 php artisan route:cache,確認生成bootstrap/cache/routes.php

  • 瀏覽器訪問 Laravel 應用程序歡迎頁確保正常訪問。

  • 運行 ab -t 10 -c http://myurl.com/index.php

 

4.2 數據記錄

4.3 對比結果

與步驟 3 結果比較發現:開啓路由信息緩存以後,每秒處理請求數從 36-38 上升到 60 左右,請求響應時間從 260ms 降低到 160ms 左右,效果顯著,從 TPS 看,提高了 70%。

5. 刪除沒必要要的中間件

 

5.1 操做

 

  • 在步驟 4 基礎上,註釋掉沒必要要的中間件代碼。

  • 瀏覽器訪問 Laravel 應用程序歡迎頁確保正常訪問。

  • 運行 ab -t 10 -c http://myurl.com/index.php

注意:此次測試中我註釋掉了全部的中間件。實際狀況中應該儘可能只留下必要的中間件。

5.2 數據記錄

5.3 對比結果

與步驟 4 結果比較發現:刪除了沒必要要的中間件以後,每秒處理請求數從 60 左右上升到 90 左右,請求響應時間從 160ms 降低到 110ms 左右,效果很是明顯,從 TPS 看,提高了 50%。

6. 開啓類映射加載優化

 

6.1 操做

 

  • 在步驟 5 基礎上,運行 php artisan optimize --force,確認生成bootstrap/cache/compiled.php 和 bootstrap/cache/services.json

  • 瀏覽器訪問 Laravel 應用程序歡迎頁確保正常訪問。

  • 運行 ab -t 10 -c http://myurl.com/index.php

 

6.2 數據記錄

6.3 對比結果

與步驟 5 結果比較發現:作了類映射加載優化以後,每秒處理請求數從 90 上升到 110,請求響應時間從 110ms 降低到 100ms 如下,效果仍是比較明顯的。

7. 關閉 OPcache

 

7.1 操做

 

  • 在步驟 6 基礎上,關閉 PHP 的 OPcache,並重啓服務器。經過 phpinfo() 的 Zend OPcache 確認 OPcache 已經關閉。

  • 瀏覽器訪問 Laravel 應用程序歡迎頁確保正常訪問。

  • 運行 ab -t 10 -c http://myurl.com/index.php

 

7.2 數據記錄

7.3 對比結果

與步驟 6 結果比較發現:關閉 OPcache 以後,每秒處理請求數從 110 降低到 15,請求響應時間從 100ms 如下上升到 650ms 以上。開啓與關閉 OPcache,數據上竟有幾倍的差異。

此後,我從新開啓了 PHP 的 OPcache,數據恢復到步驟 6 水平。

5). 踩過的坑

1. [LogicException] Unable to prepare route [/] for serialization. Uses Closure.

在運行 php artisan route:cache 命令時報這個錯誤。

緣由:路由文件中處理「/」時使用了閉包的方式。要運行該命令,路由的具體實現不能使用閉包方式。

修改方案:將路由的具體實現放到控制器中來實現。

2. [Exception] Serialization of 'Closure' is not allowed.

在運行 php artisan route:cache 命令時報這個錯誤。

緣由:路由文件中定義了重複的路由。

修改方案:排查路由文件中的重複路由並修改。尤爲要注意 resource 方法極可能致使與其方法重複。

3. [RuntimeException] Invalid filename provided.

在運行 php artisan optimize --force 命名時報這個錯誤。

緣由:在加載須要編譯的類時沒有找到相應的文件。5.2 版本的 vendor/laravel/framework/src/Illuminate/Foundation/Console/Optimize/config.php 中定義了要編譯的文件路徑,但不知道爲何 /vendor/laravel/framework/src/Illuminate/Database/Eloquent/ActiveRecords.php 沒有找到,因此報了這個錯誤。

修改方案:暫時註釋掉了以上 config.php 中的 ../ActiveRecords.php 一行。

4. InvalidArgumentException in FileViewFinder.php line 137: View [welcome] not found.

在運行 php artisan config:cache 以後,瀏覽器上訪問 Laravel 應用程序歡迎頁報這個錯誤。

緣由:Laravel 應用程序服務器是經過 Homestead 在虛擬機上搭建的。而這個命令我是在虛擬機以外運行的,致使生成的 config.php 中的路徑是本機路徑,而不是虛擬機上的路徑。因此沒法找到視圖文件。

修改方案:ssh 到虛擬機內部運行該命令。

6). 實踐技巧

坑也踩了,測試也作過了。這裏針對此次經歷作個實踐技巧的簡單總結。

1. 有效的 Laravel 應用程序優化技巧

 

  1. 關閉應用debug app.debug=false

  2. 緩存配置信息 php artisan config:cache

  3. 緩存路由信息 php artisan router:cache

  4. 類映射加載優化 php artisan optimize(包含自動加載優化 composer dumpautoload

  5. 根據須要只加載必要的中間件

  6. 使用即時編譯器(JIT),如:HHVM、OPcache

 

2. 編寫代碼時注意事項

 

  1. 路由的具體實現放到控制器中。

  2. 不定義重複的路由,尤爲注意 resouce 方法。

  3. 弄清各中間件的做用,刪除沒必要要的中間件引用。

7). 下一步

以上的調優技巧及編碼注意事項主要針對框架自己,在真正的業務邏輯編碼中有不少具體的優化技巧,在此沒有討論。

後續的優化重點將會放在具體編碼實踐上:

  1. 使用 Memcached 來存儲會話 config/session.php

  2. 使用專業的緩存驅動器

  3. 數據庫請求優化

  4. 爲數據集書寫緩存邏輯

  5. 前端資源合併 Elixir

相關文章
相關標籤/搜索