阿里雲 ACE(App Cloud Engine)緩存服務與標準 Memcached/OCS 協定不同,無法直接使用 Laravel 內建驅動。本文詳細說明如何透過實作 StoreInterface 介面,將 ACE 緩存整合為 Laravel 自訂快取驅動。
Laravel 的快取系統核心是 Illuminate\Cache\Repository,它依賴實作 StoreInterface 的儲存類別。內建 Memcached 驅動的建立流程為:
Memcached 物件MemcachedStoreRepositoryACE 緩存物件由 Alibaba::Cache('空間名稱') 取得,方法集有限,不相容 MemcachedStore,因此需自行實作儲存類別。
在 app/config/cache.php 新增 ACE 空間名稱:
'ace' => 'lblog-cache',
於 src/Ace/AceMemcachedStore.php 實作 StoreInterface:
<?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 = '') {
$this->memcached = \Alibaba::Cache($space);
$this->prefix = strlen($prefix) > 0 ? $prefix . ':' : '';
}
public function get($key) {
$value = $this->memcached->get($this->prefix . $key);
return is_bool($value) && $value === false ? null : $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) {
return $this->memcached->set($this->prefix . $key, $value, 0);
}
public function forget($key) {
return $this->memcached->delete($this->prefix . $key);
}
public function flush() {
// ACE 不支援全量清除
return false;
}
public function getMemcached() {
return $this->memcached;
}
public function getPrefix() {
return $this->prefix;
}
}
關鍵點:get() 方法需將 ACE 回傳的 false 轉為 null,符合 Laravel 判斷快取是否存在的邏輯。
在 bootstrap/start.php 中擴充:
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);
});
修改 app/config/cache.php:'driver' => 'ace'
ACE 緩存僅支援單鍵操作,flush() 無效。日常使用 Cache::put()、get()、has()、remember() 等方法皆正常運作。