PHP7.4 Preload 特性瞭解與理解

原文鏈接 何曉東 博客php

確保你的 php 是的 7.4 版本,preload 是 7.4 版本新特性
基礎瞭解

  根據 rfc 描述,Preload 簡明翻譯是預加載,是基於 opcache 的一層升級,也是 opcache 的一部分。現有的 opcache 存儲文件能夠消除編譯開銷,但從緩存中獲取文件並獲取特定請求的上下文仍有相關成本。PHP 仍然須要檢查源文件是否已被修改,將類和函數的某些部分從共享內存緩存複製到進程內存等。值得注意的是,因爲每一個 PHP 文件都徹底獨立於任何其餘文件進行編譯和緩存,所以在將文件存儲在 opcode 緩存中時,咱們沒法解決存儲在不一樣文件中的類之間的依賴關係,而且必須在每一個請求的運行時從新連接類依賴項。git

  Preload 的靈感來自爲 Java HotSpot VM 設計的"類數據共享"技術。它旨在爲用戶提供以傳統 PHP 模型提供的某些靈活性來換取性能的能力。在服務啓動時(在運行任何應用程序代碼以前),咱們可能會將一組特定的 PHP 文件加載到內存中,並使其內容"永久可用"到該服務器將處理的全部後續請求。這些文件中定義的全部函數和類均可以對現成的請求使用,與內部實體(例如 strlen() 或異常)徹底同樣。經過這種方式,咱們能夠預加載整個或部分框架,甚至整個應用程序類庫。它還將容許引入以 PHP 編寫的"內置"函數(相似於 HHVM 的 sytemlib)。換算的靈活性包括服務器啓動後沒法更新這些文件(在文件系統上更新這些文件不會執行任何操做;須要從新啓動 fpm 服務才能應用更改。此外,此方法與承載多個應用程序的服務器或多個版本的應用程序(對於具備相同名稱的某些類具備不一樣的實現)不兼容,若是此類從一個應用的代碼庫預加載,則與從其餘應用加載不一樣的類實現將發生衝突。github

上手使用

總體就是開啓,配置一下腳本文件,設置用戶就行。首先須要修改配置文件 php.iniweb

[opcache]
zend_extension=opcache.so
opcache.enable=1             # 啓用 opcache
opcache.enable_cli=1         # 僅針對 CLI 版本的 PHP 啓用操做碼緩存。一般被用來測試和調試。
opcache.preload=preload.php  # preload 腳本路徑
opcache.preload_user=web     # preload 用戶,安全考慮禁止 root 用戶

對應 preload.php 文件,能夠引入其餘文件:緩存

<?php

function xx()
{
    return 'hello preload!';
}

opcache_compile_file('other.php');

若是須要引入composer編譯後的文件,能夠這樣:安全

<?php

$files = require __DIR__ . '/composer/autoload_classmap.php';

foreach (array_unique($files) as $file) {
    opcache_compile_file($file);
    // require_once($file);
}

一個要點是:若是你寫了幾個文件名稱,而沒有寫他們的依賴文件,例如接口,trait 和父類,將會拋出警告,實際上沒有預加載成功,將 opcache_compile_file 函數換成 require_once 函數就行,參見 opcache-compile-file 方法服務器

還要一個第三方包協助生成 preload 腳本 -- Composer-Preload,用法能夠參考詞包的 README。對於 composer 官方,issue 中有討論,可能會在 2.0 里程碑版本推出這個特性。php7

侷限性及注意點
  • 一個 php 只能有一個preload 配置選項,對於多項目的狀況是侷限性,相似共享虛擬雲主機的狀況沒法解決。
  • 一臺服務器的話,php-fpm 重啓過程當中會有少許時間消耗,這個時間會斷開全部的連接,這個是須要評估的狀況,能夠考慮在深夜重啓。多臺主從服務器或者有高可用(HA)方案的時候,能夠踢掉一臺,重啓一下 php-fpm 再加入就行,只是時間操做的成本,沒有技術隱患。(涉及到另外一個問題:php-fpm reload 的狀況下,肯定你的 worker 進行真正的所有 reload 了一下,有些狀況下,有較長時間的定時任務在處理,必須等這個鏈接忙完才真正 reload,或者受 process_control_timeout 配置項影響,多久時間不完成就強制結束並重啓,若是沒有這個狀況,php-fpm restart 最簡單直接)。
  • 須要加載的文件很少的話,不能帶來顯著的提高,只有大的框架項目值得去預加載。須要評估是否加載 verdor 中所有的文件,文件越多須要的內存越大,只加載最關鍵的部分是最好的選擇,較少的內存資源佔用並帶來性能提高。
  • 大框架多文件預加載狀況下,遍歷文件加入到 opcache 的預熱過程須要消耗 CPU 資源,必要而短暫的耗時。

最大的隱患是技術人員在開發環境沒有充分的場景測試一下,不肯意直接在生產環境啓用composer

參考連接:框架

  1. github issue:An attempt to implemnt "preloading" ability. 主要看一下 Dmitry Stogov 大佬的解釋。
  2. github issue:Preloading support
  3. RFC Preload
  4. Introduction to PHP 7.4 Preload
  5. Composer: How it should preload in PHP 7.4
  6. Opcache 配置選項手冊
  7. Preloading in php7.4

© 原創文章,若有錯誤或指正 請聯繫 hexiaodong1992@outlook.com

順帶推薦點課程 -> 去了解

相關文章
相關標籤/搜索