CacheEventListenerの実装を作ってみる
ダメだ、眠れない、、、。
ということで、今回は、CacheEventListenerのサンプルとして AmountOverflowAlarm を作成してみます。(こんな夜更けに、、、。)
AmountOverflowAlarm
AmountOverflowAlarm クラスとして、キャッシュへの put 後に、以前と現在の要素数を調べ、設定値を超えてたら警告ログを出力するクラスを作成します。
CacheEventAdapter
CacheEventListenerには、8つのメソッドが定義されています。しかし、AmountOverflowAlarm クラスでは put の監視しかする必要がありません。そのため、8つのメソッドをすべて実装するのは面倒です。そのため、CacheEventListener の空実装として、CacheEventAdapter を作成します。
public class CacheEventAdapter implements CacheEventListener { public Object clone() throws CloneNotSupportedException { return super.clone(); } public void notifyElementEvicted(Ehcache cache, Element element) {} public void notifyElementExpired(Ehcache cache, Element element) {} public void notifyElementPut(Ehcache cache, Element element) throws CacheException {} public void notifyElementRemoved(Ehcache cache, Element element) throws CacheException {} public void notifyElementUpdated(Ehcache cache, Element element) throws CacheException {} public void notifyRemoveAll(Ehcache cache) {} public void dispose() {} }
ehcache-amountOverflowAlermSample.xml
このサンプル用の、Ehcacheの定義ファイルです。
<ehcache> <defaultCache /> <!-- このキャッシュは、要素数が1000件超えることがないと考えた上で設定されています。 しかし、サービスが拡大して、そのうち1000件を超えるかもしれない、、、。 そうなると、パフォーマンスチューニングを見直さなくてはならないなぁ。 --> <cache name="testCache" maxElementsInMemory="1000" eternal="true" overflowToDisk="false" > <!-- とうことで、900件を超えるタイミングで、警告ログを出します。 --> <cacheEventListenerFactory class="AmountOverflowAlarmFactory" properties="threshold=900" /> </cache> </ehcache>
AmountOverflowAlarm
これが、今回の主役です。CacheEventListener で定義されているメソッドのうち、notifyElementPut メソッドのみ使用しています。警告ログを出す要素数の閾値 は、threshold にセットします。キャッシュにputされるたびに notifyElementPut メソッドが呼び出されて、メモリ上の要素数が threshold を超えた場合には警告ログが出力されます。
public class AmountOverflowAlarm extends CacheEventAdapter { private static final Log LOG = LogFactory.getLog(Cache.class.getName()); private long threshold; private long lastAmount = -1; public AmountOverflowAlarm(long threshold) { setThreshold(threshold); } public void setThreshold(long threshold) { this.threshold = threshold; } public void notifyElementPut(Ehcache cache, Element element) throws CacheException { // Get current number of cache elements long amount = cache.getMemoryStoreSize(); // Alert if (lastAmount < threshold && amount >= threshold) { LOG.warn("Number of elements in cache '" + cache.getName() + "' is over " + threshold + "."); } // Save current amount this.lastAmount = amount; } }
AmountOverflowAlarmFactory
定義ファイル上でキャッシュに CacheEventListener を設定するためにはファクトリが必須となるため、AmountOverflowAlarmFactory を作成します。
public class AmountOverflowAlarmFactory extends CacheEventListenerFactory { public CacheEventListener createCacheEventListener(Properties properties) { return new AmountOverflowAlarm(Long.parseLong(properties.getProperty("threshold"))); } }
AmountOverflowAlermSample
AmountOverflowAlerm のサンプルプログラムです。定義ファイル ehcache-amountOverflowAlermSample.xml で CacheManager を設定し、testCache にデータを1000件投入します。
/** * CacheEventListenerのサンプル * キャッシュ "testCache" に対して、データを1000件投入します。 */ public class AmountOverflowAlermSample { public static void main(String[] args) { URL url = ClassLoader.getSystemResource("ehcache-amountOverflowAlermSample.xml"); CacheManager cm = new CacheManager(url); // キャッシュを取得する。 Cache test = cm.getCache("testCache"); // テストデータを1000件投入。 for (int i=0; i<1000; i++) test.put(new Element(new Object(), new Object())); } }
結果。
900件を越えたタイミングで警告ログが出力されました。
2008/04/22 9:09:51 AmountOverflowAlarm notifyElementPut 警告: Number of elements in cache 'testCache' is over 900.
めでたしめでたし。