iT邦幫忙

2025 iThome 鐵人賽

DAY 20
0
Modern Web

Laravel 12 開發者幸福度升級指南系列 第 20

Day 20:在 Laravel 內加上快取,並在雲端上面部署

  • 分享至 

  • xImage
  •  

上次透過避免 N+1 問題,我們減少了對資料庫操作的消耗,來避免系統出現效能問題。

不過要能夠在有限的資源下,服務更多的用戶,通常我們會在使用一些方式優化系統。

下面我們來說使用快取來優化系統的方式。

快取

在 Laravel 裡面,我們可以透過把常用的資訊放到運作較快的地方,來提升資料儲存的效率。

目前在正式環境的習慣通常是放在 Redis 裡面。

測試環境為了簡化開發,預設是放在資料庫裡面。所以我們可以很簡單的用 DB::enableQueryLog() 看到效果

比方說,昨天的程式碼

$users = User::with('books')->get();
$books = collect();
foreach ($users as $user) {
    $userData = collect();
    foreach ($user->books as $book) {
        $userData->push($book->title);
    }
    $books->push($user);
}

我們可以加上一段 Cache::remember 的邏輯,變成

Route::get('/books', function () {
    DB::enableQueryLog();
    $users = Cache::remember('users_with_books', 600, function () {
        return User::with('books')->get(); // 避免 N+1
    });
    $books = collect();
    foreach ($users as $user) {
        $userData = collect();
        foreach ($user->books as $book) {
            $userData->push($book->title);
        }
        $books->push($user);
    }
    return DB::getQueryLog();
})->name('books');

這時候我們存取 http://127.0.0.1:8000/books 就會看到

[
  {
    "query": "select * from \"cache\" where \"key\" in (?)",
    "bindings": [
      "laravel_cache_users_with_books"
    ],
    "time": 0.19
  },
  {
    "query": "select * from \"users\"",
    "bindings": [],
    "time": 0.1
  },
  {
    "query": "select * from \"books\" where \"books\".\"user_id\" in (1, 2, 3, 4)",
    "bindings": [],
    "time": 0.28
  },
  {
    "query": "insert into \"cache\" (\"expiration\", \"key\", \"value\") values (?, ?, ?) on conflict (\"key\") do update set \"expiration\" = \"excluded\".\"expiration\", \"key\" = \"excluded\".\"key\", \"value\" = \"excluded\".\"value\"",
    "bindings": [
      1758464248,
      "laravel_cache_users_with_books",
      "TzozOT..."
    ],
    "time": 0.78
  }
]

這邊先是試著存取快取的資料表,發現沒有資料之後,改存取 usersbooks 兩張資料表,之後將取得的資料寫入 cache 資料表內。

如果我們再存取一次,就會看見

[
  {
    "query": "select * from \"cache\" where \"key\" in (?)",
    "bindings": [
      "laravel_cache_users_with_books"
    ],
    "time": 0.36
  }
]

由於快取內有我們要的資料,所以我們只要直接從裡面取出資料即可。

在 Laravel Cloud 上面建置快取

程式撰寫完畢之後,接著我們要在雲端上面建立快取,讓線上的使用者能夠使用到快取的好處。

我們將這段程式碼推到雲端之後,試著存取雲端上的 /books 這個網頁看 Query Log

[
  {
    "query": "select * from \"cache\" where \"key\" in (?)",
    "bindings": [
      "ithome2025_cache_users_with_books"
    ],
    "time": 43.38
  }
]

我們重新整理之後,會看到即使是拿快取,一樣是存取資料庫

要像是前面所說,存取 Redis 裡面的內容,我們要在 Laravel Cloud 上面加上快取服務

我們可以點擊「Environment」裡面的「Cache」

Laravel Cloud Cache

點擊並安裝之後,我們再次重整畫面看 Query Log,就會看到已經不會透過存取資料庫來取得內容了。所以我們會看到空的 Query Log

[]

今天的部分就到這邊,我們明天見!


上一篇
Day 19:laravel 12 的 N+1 問題以及解法
系列文
Laravel 12 開發者幸福度升級指南20
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言