阿里雲 ACE (App Cloud Engine) 快取服務與標準 Memcached 介面差異較大,無法直接復用 Laravel 內建驅動。本文展示如何實作 Illuminate\Cache\StoreInterface 建立專用 ACE 快取驅動,達成無縫整合。
| 特性 | 標準 Memcached | 阿里雲 ACE 快取 |
|---|---|---|
| 取得實例 | new Memcached() | Alibaba::Cache('空間名稱') |
| 支援方法 | 完整 Memcached API | 有限:get/set/increment/decrement/delete |
| Flush 操作 | 支援 | 不支援 |
| 認證方式 | SASL/無 | 平台內建認證 |
Cache::extend('ace', ...)
→ AceMemcachedStore (實作 StoreInterface)
→ Alibaba::Cache() 實例
→ Repository
<?php
// app/config/cache.php
return [
'driver' => 'file',
// ... 其他配置 ...
// 新增 ACE 配置
'ace' => 'your-cache-space-name', // 控制台建立的快取空間名稱
];
// 專案根目錄
src/
└── Ace/
└── AceMemcachedStore.php
// composer.json
"autoload": {
"classmap": [...],
"psr-4": {
"Ace\\": "src/Ace"
}
}
執行 composer dump-autoload
<?php
// src/Ace/AceMemcachedStore.php
namespace Ace;
use Illuminate\Cache\StoreInterface;
use Illuminate\Cache\TaggableStore;
class AceMemcachedStore extends TaggableStore implements StoreInterface {
protected $memcached;
protected $prefix;
public function __construct($space, $prefix = '') {
// 取得 ACE 快取實例
$this->memcached = \Alibaba::Cache($space);
$this->prefix = strlen($prefix) > 0 ? $prefix . ':' : '';
}
// 關鍵:get() 必須回傳 null 而非 false
public function get($key) {
$value = $this->memcached->get($this->prefix . $key);
// ACE 回傳 false 表示不存在,Laravel 期望 null
if (is_bool($value) && $value === false) {
return null;
}
return $value;
}
public function put($key, $value, $minutes) {
return $this->memcached->set($this->prefix . $key, $value, $minutes);
}
public function increment($key, $value = 1) {
return $this->memcached->increment($this->prefix . $key, $value);
}
public function decrement($key, $value = 1) {
return $this->memcached->decrement($this->prefix . $key, $value);
}
public function forever($key, $value) {
// ACE: 0 表示永不過期
return $this->memcached->set($this->prefix . $key, $value, 0);
}
public function forget($key) {
return $this->memcached->delete($this->prefix . $key);
}
public function flush() {
// ACE 不支援 flush,回傳 false 表示失敗
return false;
}
public function getMemcached() {
return $this->memcached;
}
public function getPrefix() {
return $this->prefix;
}
}
<?php
// bootstrap/start.php
// 在 return $app; 之前
Cache::extend('ace', function ($app) {
$space = $app['config']['cache.ace'];
$prefix = $app['config']['cache.prefix'];
$store = new \Ace\AceMemcachedStore($space, $prefix);
return new \Illuminate\Cache\Repository($store);
});
<?php
// app/config/cache.php
'driver' => 'ace',
Laravel Repository::get() 判斷邏輯:
public function get($key, $default = null) {
$value = $this->store->get($key);
return $value === null ? $default : $value; // 嚴格檢查 null
}
ACE get() 回傳 false 表示不存在,必須轉換為 null,否則 Cache::has()、Cache::get() 預設值邏輯會失效。
Cache::tags())StoreInterface 所有必要方法ACE 不支援全量清除,回傳 false 讓上層知道操作失敗,而非靜默成功導致資料不一致預期。
<?php
// 新增快取,10 分鐘過期
Cache::put('my_key', 'my value', 10);
// 讀取快取
$value = Cache::get('my_key');
// 判斷存在
if (Cache::has('my_key')) { ... }
// 模型查詢快取
$users = DB::table('users')->remember(10)->get();
// 遞增/遞減
Cache::increment('counter');
Cache::decrement('counter', 5);
// 這行會回傳 false,不會清除快取
Cache::flush();
// 標籤功能視 ACE 底層支援度而定
Cache::tags(['users', 'posts'])->put('key', 'value', 10);
<?php
namespace Ace;
use Illuminate\Cache\StoreInterface;
use Illuminate\Cache\TaggableStore;
class AceMemcachedStore extends TaggableStore implements StoreInterface {
// ... 現有屬性 ...
protected $connected = false;
public function __construct($space, $prefix = '') {
$this->space = $space;
$this->prefix = strlen($prefix) > 0 ? $prefix . ':' : '';
}
// 延遲連線:首次操作時才建立連線
protected function getConnection() {
if (!$this->connected) {
$this->memcached = \Alibaba::Cache($this->space);
$this->connected = true;
}
return $this->memcached;
}
public function get($key) {
try {
$value = $this->getConnection()->get($this->prefix . $key);
return is_bool($value) && $value === false ? null : $value;
} catch (\Exception $e) {
\Log::error("ACE Cache GET error: {$e->getMessage()}");
return null; // 降級:快取失效視同不存在
}
}
// 其他方法同理加上 try-catch 與 getConnection()
// ...
}
實作阿里雲 ACE 快取驅動核心在於:
false → null 確保邏輯正確此模式適用於任何非標準快取服務整合:只要實作 StoreInterface 11 個方法,即可無縫接入 Laravel 快取體系。掌握此技能,能讓 Laravel 在任何雲平台、任何儲存後端上發揮最大效能優勢。