快取對於實現高效能和可擴充套件性至關重要。從開發階段就實施正確的快取策略對於避免滯後的API和緩慢的頁面載入時間至關重要。Laravel是最流行的PHP框架之一,因此實現最佳的Laravel快取策略對於更好的使用者體驗和更大的業務影響是必不可少的。
在本文中,我們將探討在Laravel中實現和操作快取的策略。您將瞭解Laravel快取的工作原理、幾個Laravel快取查詢,以及如何處理Laravel應用程式上的快取。
如果您已經掌握了以下方面的基本知識,您將從本文中獲得更多資訊:
- 良好的網路開發知識
- Laravel的基本理解
- 使用Laravel構建API
- 快取的基本理解
本文將從五個方面全面介紹Laravel快取相關知識內容,希望對您有一定的幫助!
為什麼快取很重要?
隨著最近網際網路業務的蓬勃發展,不同公司的統計資料顯示網站載入時間和低效能如何在沒有快取的情況下嚴重影響SEO、使用者參與度和對話率。這從一個出色的快取策略開始。
一項線上研究發現,“1秒的載入延遲時間將使亞馬遜每年損失16億美元的銷售額。”
谷歌的另一項研究報告稱,“我們的研究表明,如果搜尋結果慢了幾分之一秒,人們的搜尋就會減少(嚴重的是:400毫秒的延遲會導致搜尋量下降0.44%)。這種不耐煩不僅限於搜尋:如果視訊在載入時停頓,五分之四的網際網路使用者會點選離開。”
您的網頁載入時間稍有遲緩可能會對您的使用者體驗產生巨大影響並導致資金損失。
什麼是Laravel快取?
Laravel提供了一個健壯且易於使用的快取和不同快取後端的實現。使用Laravel快取,您無需編寫任何程式碼即可在多個快取引擎之間高效切換。
您可以在config/cache.php
資料夾中找到Laravel快取的配置,但您可能只需要.env檔案即可在不同的快取後端之間切換。
Laravel快取還提供了許多實用的方法,我們可以使用它們來實現不同的快取策略。
Laravel快取驅動程式和比較
Laravel快取提供了很棒的快取後端和驅動程式。根據您的用例,您可以在它們之間切換以提高應用程式效能和載入時間。
也就是說,Laravel快取還提供了一種無縫方式來建立自定義後端並將其與Laravel快取一起使用,但前提是下面的列表不適合您的用例。
接下來我們將討論Laravel快取提供的所有後端列表。
1.檔案
當.env檔案中沒有指定驅動程式時,檔案驅動程式是Laravel快取使用的預設後端。
檔案後端被設計為快取記憶體的資料儲存在下找到的加密檔案storage/framework/
。當快取新資料時,Laravel會使用資料和快取金鑰建立一個加密檔案。當使用者嘗試檢索內容時也會發生同樣的情況。Laravel快取在資料夾中搜尋指定的鍵,如果找到,則返回內容。
雖然檔案後端工作完美,節省了安裝和配置外部驅動程式的時間,但它也非常適合開發。它比直接從資料庫伺服器訪問資料要快。
要使用檔案驅動程式,請將以下程式碼新增到.env檔案中:
CACHE_DRIVER=file
2. 陣列
陣列驅動器是用於執行自動化測試完美快取後端並與Github上操作,詹金斯等容易地構成
陣列後端儲存在PHP中的陣列快取的資料,並且不需要你安裝或配置任何驅動程式。它非常適合自動化測試,並且比檔案快取後端快一點。
要使用陣列驅動程式,請將以下程式碼新增到.env檔案中:
CACHE_DRIVER=array
3. 資料庫
使用資料庫驅動程式時,資料儲存在當前PHP程序的記憶體中。因此,您需要建立一個資料庫表來儲存快取的資料。此外,資料庫快取通過將查詢工作負載從後端分配到多個前端來提高可伸縮性。
您可以執行這個Artisan命令——php artisan cache:table
自動生成資料庫驅動程式所需的資料庫模式。
資料庫驅動程式主要用於情況下您可以在主機平臺上安裝任何軟體。
例如,假設您使用的是選項有限的免費託管計劃。為此,我們建議堅持使用檔案驅動程式,因為在大多數情況下,資料庫驅動程式是應用程式的最薄弱點,並且試圖將更多資料推入該瓶頸並不是一個好主意。
要使用資料庫驅動程式,請將以下程式碼新增到.env檔案中:
CACHE_DRIVER=database
4. Redis
redis驅動程式使用記憶體為基礎的快取技術被稱為Redis。儘管與上面討論的其他快取驅動程式相比它很快,但它需要安裝和配置外部技術。
要使用redis驅動程式,請將以下程式碼新增到.env檔案中:
CACHE_DRIVER=redis
5. 記憶體快取
眾所周知,Memcached是最流行的基於記憶體的快取儲存。如果你不介意一些額外的伺服器維護(必須安裝和維護額外的服務),基於記憶體的快取驅動程式Memcached是不錯的選擇。
使用memcached驅動程式需要安裝Memcached PECL包。
要使用memcached驅動程式,請將以下程式碼新增到.env檔案中。
CACHE_DRIVER=memcached
要使用的最佳快取驅動程式和快取驅動程式的效能取決於您的專案用例和要檢索的資料量。
Laravel快取使用和方法
Laravel快取提供了許多有價值的方法用於實現許多快取策略。下面我們將列出並解釋不同的方法(按用例分類):
put()
get()
many()
putMany()
increment()
decrement()
forever()
forget()
flush()
remember()
rememberForever()
儲存快取
使用不同的方法在快取中儲存新資料非常簡單,每種方法都有幾個用例。
1. Cache::put()
該方法接受三個關鍵引數, duration和要快取的data。讓我們來看看如何使用 Cache::put()
:
Cache::put(key, data, duration) $post = Post::find(1); Cache::put('post_1', $post, 20);
上面的程式碼將使用唯一鍵快取文字20秒。
2. Cache::putMany()
此方法以相同的持續時間在快取中一次性儲存一組資料。它接受兩個引數,分別是data和seconds 。
讓我們來看看如何使用Cache::putMany()
:
Cache::putMany(data, duration) // syntax $posts = Post::all(); Cache::putMany($posts, 20);
3. Cache::remember()
此方法是另一種實現快取Aside策略的絕佳方法。這Cache::remember()
方法接受三個引數,一個key 、 seconds和closure,用於在未找到時從資料庫中檢索資料。
讓我們來看看如何使用Cache::remember():
:
Cache::remember(key, duration, closure) // syntax Cache::remember('posts', 20, function(){ return Post::all(); });
Laravel快取也有Cache::rememberForever()
方法,它不接受seconds引數並永久儲存資料。
4. Cache::forever()
此方法將資料永久儲存在快取伺服器中,無需指定任何持續時間。您可以使用以下程式碼實現它:
Cache::forever(key, data) $post = Post::find(1); Cache::forever('post_1', $post);
檢索快取資料
此類別中的方法從快取中檢索資料。根據是否找到資料,其中一些方法的行為可能有所不同。
1. Cache::get()
此方法使用特定鍵從快取伺服器檢索資料。您可以使用以下程式碼檢索專案:
Cache::get(key) // syntax $posts = Cache::get('posts');
2. Cache::many()
這種方法類似於Cache::putMany()
。它用於使用快取鍵陣列一次檢索快取資料陣列。您可以使用以下程式碼檢索快取陣列:
Cache::many(keys) // syntax const $keys = [ 'posts', 'post_1', 'post_2' ]; $posts = Cache::many($keys);
3. Cache::remember()
您還可以使用此方法通過使用提供的金鑰檢查快取伺服器來檢索快取資料。如果資料儲存在快取中,它將檢索它。否則,它將從資料庫伺服器檢索資料並將其快取。此方法與Cache::rememberForever()
方法中僅增加了一個額外的seconds引數的Cache::remember()
方法相同。
從快取中刪除專案
此類別下的方法用於從快取中刪除專案,按功能分組。
1. Cache::forget()
此方法使用指定的鍵引數從快取中刪除單個專案:
Cache :: forget ( 'key' ) ;
2. Cache::flush()
此方法清除所有快取引擎。它刪除儲存在快取中任意位置的所有專案:
Cache :: flush ( ) ;
遞增或遞減快取值
您可以分別使用increment和decrement方法調整儲存在快取中的整數值的值:
Cache::increment('key'); Cache::increment('key', $amount); Cache::decrement('key'); Cache::decrement('key', $amount);
Laravel快取有很多我們上面沒有討論的很棒的方法,但是上面的方法很流行。 您可以在官方Laravel快取文件中獲得所有方法的概述。
快取命令解釋
Laravel提供了一些命令來讓Laravel快取的使用變得簡單快捷。以下是所有命令及其功能的列表。
清除Laravel快取
此命令用於在Laravel快取過期之前使用終端/控制檯清除它。例如,您可以執行以下命令:
php artisan cache:clear
清除路由快取
此命令用於清除Laravel應用程式的路由快取。例如,執行以下命令來清除您的路由快取:
php artisan config:cache
清除編譯的檢視檔案
此命令用於清除Laravel應用程式的編譯檢視檔案。您可以使用以下命令實現它:
php artisan view : clear
資料庫表
使用資料庫驅動時,需要建立一個名為cache的資料庫模式來儲存快取資料。您還可以使用Artisan命令生成具有正確架構的遷移:
php artisan cache:table
Laravel快取策略
根據您的應用程式用例和資料結構,您可能可以使用幾種不同的快取策略。您甚至可以建立自定義策略來滿足您的需求。下面我們將介紹您可以在Laravel專案中實施的流行快取策略列表。
writeThrough
在writeThrough策略中,快取伺服器位於請求和資料庫伺服器之間,使得每個寫操作在進入資料庫伺服器之前都要經過快取伺服器。因此,writeThrough快取策略類似於readThrough策略。
您可以使用以下程式碼使用Laravel快取實現此策略:
public function writeThrough($key, $data, $minutes) { $cacheData = Cache::put($key, $data, $minutes) // Database Server is called from(after) the Cache Server. $this->storeToDB($cachedData) return $cacheData } private function storeToDB($data){ Database::create($data) return true }
writeBack (writeBehind)
此策略是通過新增寫入操作延遲來實現writeThrough策略的更高階方法。
您也可以將此稱為writeBehind策略,因為在將資料寫入資料庫伺服器之前應用於快取伺服器的時間延遲。
您可以使用以下程式碼使用Laravel快取實現此策略:
$durationToFlush = 1; // (in minute) $tempDataToFlush = []; public function writeBack($key, $data, $minutes){ return $this->writeThrough($key, $data, $minutes); } public function writeThrough($key, $data, $minutes) { $cacheData = Cache::put($key, $data, $minutes); $this->storeForUpdates($cacheData); return $cacheData; } // Stores new data to temp Array for updating private function storeForUpdates($data){ $tempData = {}; $tempData['duration'] = this.getMinutesInMilli(); $tempData['data'] = data; array_push($tempDataToFlush, data); } // Converts minutes to millisecond private function getMinutesInMilli(){ $currentDate = now(); $futureDate = Carbon(Carbon::now()->timestamp + $this->durationToFlush * 60000) return $futureDate->timestamp } // Calls to update the Database Server. public function updateDatabaseServer(){ if($this->tempDataToFlush){ foreach($this->tempDataToFlush as $index => $obj){ if($obj->duration timestamp){ if(Database::create($obj->data)){ array_splice($this->tempDataToFlush, $index, 1); } } } } }
writeBack方法呼叫writeThrough方法,該方法將資料儲存到快取伺服器和稍後使用updateDatabaseServer方法推送到資料庫伺服器的臨時陣列。您可以設定CronJob以每五分鐘更新一次資料庫伺服器。
writeAround
此策略允許所有寫入操作直接進入資料庫伺服器,而無需更新快取伺服器——僅在讀取操作期間更新快取伺服器。假設使用者想要建立一個新文章,文章直接儲存到資料庫伺服器。當使用者第一次想要閱讀文章的內容時,文章會從資料庫伺服器中檢索出來,並更新快取伺服器以供後續請求使用。您可以使用以下程式碼使用 Laravel 快取實現此策略:
此策略允許所有write操作直接進入資料庫伺服器,而無需更新快取伺服器——僅在read操作期間更新快取伺服器。
假設使用者想要建立一個新Article,Article直接儲存到資料庫伺服器。當使用者第一次想要閱讀Article的內容時,Article會從資料庫伺服器中檢索出來,並更新快取伺服器以供後續請求使用。
您可以使用以下程式碼使用Laravel快取實現此策略:
public function writeAround($data) { $storedData = Database::create($data); return $storedData; } public function readOperation($key, $minutes){ $cacheData = Cache::remember($key, $minutes, function() { return Article::all(); }) return $cacheData; }
快取擱置(延遲載入)
在此策略中,資料庫處於旁觀狀態,應用程式首先從快取伺服器請求資料。然後,如果命中(找到),則將資料返回給客戶端。否則,如果有未命中(未找到),資料庫伺服器將請求資料並更新快取伺服器以用於後續請求。
您可以使用以下程式碼使用Laravel快取實現此策略:
public function lazyLoadingStrategy($key, $minutes, $callback) { if (Cache::has($key)) { $data = Cache::get($key); return $data; } else { // Database Server is called outside the Cache Server. $data = $callback(); Cache::set($key, $data, $minutes); return $data; } }
上面的程式碼展示了cache Aside Strategy的實現,相當於實現了Cache::remember方法。
Read Through
此策略與快取Aside策略直接相反。在這個策略中,快取伺服器位於客戶端請求和資料庫伺服器之間。
請求直接傳送到快取伺服器,如果在快取伺服器中沒有找到,快取伺服器負責從資料庫伺服器檢索資料。
您可以使用以下程式碼使用Laravel快取實現此策略:
public function readThrough($key, $minutes) { $data = Cache::find($key, $minutes); return $data; } private function find($key, $minutes){ if(Cache::has($key);){ return Cache::get($key); } // Database Server is called from the Cache Server. $DBdata = Database::find($key); Cache:put($key, $DBdata, $minutes); return $DBdata; }
有了它!我們現在已經為您的下一個Laravel應用程式討論了一些流行的快取策略。請記住,您甚至可以使用最適合您的專案要求的自定義快取策略。
快取Laravel應用程式的UI部分
快取我們的Laravel應用程式的UI是一個稱為全頁面快取FPC的概念。該術語指的是快取來自應用程式的HTML響應的過程。
它非常適合動態HTML資料不經常更改的應用程式。您可以快取HTML響應,以便更快地整體響應和呈現HTML。
我們可以使用以下程式碼行來實現FPC:
class ArticlesController extends Controller { public function index() { if ( Cache::has('articles_index') ) { return Cache::get('articles_index'); } else { $news = News::all(); $cachedData = view('articles.index')->with('articles', $news)->render(); Cache::put('articles_index', $cachedData); return $cachedData; } } }
乍一看,您可能已經注意到,我們會檢查該articles_index頁面是否已存在於我們的快取伺服器中。然後我們通過使用Laravel的view()和render()方法渲染它來返回頁面。否則,在將呈現的頁面返回給瀏覽器之前,我們渲染頁面並將輸出儲存在我們的快取伺服器中以用於後續請求。
構建一個Laravel應用
現在我們將通過建立一個新的 Laravel 專案並實現 Laravel 快取來應用我們迄今為止學到的知識。
如果您還沒有使用過Laravel,您可以先了解Laravel,並閱讀優秀的Laravel教程再開始使用。
設定Laravel
首先,我們將使用以下命令建立一個新的Laravel例項。您可以檢視官方文件瞭解更多資訊。
在執行以下命令之前,開啟您的控制檯並導航到您儲存PHP專案的位置。確保已正確安裝和配置Composer。
composer create-project laravel/laravel fast-blog-app // Change directory to current Laravel installation cd fast-blog-app // Start Laravel development server. php artisan serve
配置和填充資料庫
接下來,我們將建立我們的資料庫,建立一個新的文章模型,並填充500個假資料點進行測試。
開啟您的資料庫客戶端並建立一個新資料庫。我們將對名稱fast_blog_app_db執行相同的操作,然後使用資料庫憑據填充我們的.env檔案:
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=fast_blog_app_db DB_USERNAME=//DB USERNAME HERE DB_PASSWORD=//DB PASSWORD HERE
接下來,我們將執行以下命令來同時建立遷移和文章模型:
php artisan make:model Article -m
開啟新建立的遷移找到的database/migrations/xxx-create-articles-xxx.php
,貼上如下程式碼:
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateArticlesTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('articles', function (Blueprint $table) { $table->id(); $table->string('title'); $table->text('description'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('articles'); } }
接下來,執行下面的命令來建立一個新的seeder:
php artisan make:seeder ArticleSeeder
在database/seeders/ArticleSeeder.php
找到的新建立的seeder檔案並貼上以下程式碼:
<?php namespace Database\Seeders; use App\Models\Article; use Illuminate\Database\Seeder; class ArticleSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { Article::factory()->count(500)->create(); } }
開啟同目錄下的DatabaseSeeder.php檔案,新增如下程式碼:
<?php namespace Database\Seeders; use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { /** * Seed the application's database. * * @return void */ public function run() { $this->call(ArticleSeeder::class); } }
接下來,執行以下命令來建立一個新factory:
php artisan make:factory ArticleFactory
在database/factories/ArticleFactory.php
找到並開啟新建的factory檔案,貼上如下程式碼:
<?php namespace Database\Factories; use App\Models\Article; use Illuminate\Database\Eloquent\Factories\Factory; class ArticleFactory extends Factory { /** * The name of the factory's corresponding model. * * @var string */ protected $model = Article::class; /** * Define the model's default state. * * @return array */ public function definition() { return [ 'title' => $this->faker->text(), 'description' => $this->faker->paragraph(20) ]; } }
現在,執行下面的命令來遷移我們新建立的模式,併為我們的假資料做種子測試:
php artisan migrate --seed
建立文章控制器
接下來,我們將建立我們的控制器並設定我們的路由來處理我們的請求並使用上述模型檢索資料。
執行以下命令在app/Http/Controllers
資料夾中建立一個新的ArticlesController:
php artisan make:controller ArticlesController --resource
開啟檔案並將以下程式碼新增到類中:
// Returns all 500 articles with Caching public function index() { return Cache::remember('articles', 60, function () { return Article::all(); }); } // Returns all 500 without Caching public function allWithoutCache() { return Article::all(); }
之後,在routes/
資料夾中找到並開啟api.php檔案並貼上以下程式碼以建立一個端點,我們可以呼叫它來檢索我們的資料:
Route::get('/articles', 'ArticlesController@index'); Route::get('/articles/withoutcache', 'ArticlesController@allWithoutcache');
測試效能
最後,我們將測試應用程式在是否使用 Laravel 快取的情況下的響應效能。
這張截圖顯示了應用程式介面在使用快取後的響應時間:
帶快取的Laravel API響應時間
以下螢幕截圖顯示了未實現快取的API的響應時間 – 請注意,響應時間比快取例項增加了5,000%以上:
沒有快取的Laravel API響應時間
小結
我們通過構建一個新專案、對其響應進行基準測試並比較結果,探索了實施和操縱 Laravel 快取的各種策略。
你還學會了如何使用不同的 Laravel 快取驅動和方法。此外,我們還實施了不同的快取策略,幫助你找出適合自己的快取策略。
如需瞭解更多 Laravel 資訊,請瀏覽我們精心挑選的最佳 Laravel 教程。無論你是初學者還是高階 Laravel 開發人員,這裡都有適合每個人的內容!
評論留言