2012-02-23 38 views
4

我需要跟蹤特定時間範圍內的某些事件,並在事件數量達到特定數量時採取行動。更詳細地說,我連接到外部服務並提交確認狀態等於CONF或FAIL的請求。我需要能夠監視響應以檢測在給定時間範圍內是否有不尋常的失敗次數,例如, > 3在最後5秒內失敗,以便我可以檢查錯誤並採取相應措施。我可以選擇檢查連續3次失敗,但我更喜歡基於時間的方法。Java收集過期條目

我一直在測試番石榴閱讀本post後的CacheLoader但同時條目(我只存儲FAIL事件)在Cache中出現的呼叫到期的預期,以size()(以確定失敗的次數)亦包括過期的條目。這似乎是它應該如何工作根據documentation,如果我沒有誤解的事情?有沒有辦法從緩存中獲取「活動」事件的數量?

我猜想另一種解決方案是使用像Esper這樣的CEP框架,但對於我的簡單需求來說,它看起來像是矯枉過正和麻煩。有沒有人有完全不同的方法來建議,以促進我的要求?由於

+1

你看到什麼'EhCache'緩存框架?我建議看看它。我認爲解決你的要求。請參閱http://ehcache.org/ – MJM 2012-02-23 13:49:38

+2

我想我不明白這個問題。發送到外部服務。如果錯誤響應,則添加到帶有時間戳的隊列中。刪除太舊的項目。如果列表長度>閾值,則執行一些操作。如果這種方法證明太慢,那麼(並且只有這樣)才能優化。一旦優化成爲可以使用整數圖,其中地圖的關鍵是幾秒鐘的時間。當你添加一個錯誤時(使用秒作爲鍵,遞增計數),你確切地知道還有哪些其他鍵可以相加。 – 2012-02-23 14:03:56

+0

@TonyEnnis我不明白常規隊列如何解決我的問題。我需要有某種迭代過程來監視和刪除不能成爲所需解決方案的條目。 – hgus1294 2012-02-23 16:26:05

回答

6

充分利用Cache活性元素的確切數目將需要鎖定整個緩存,這是極其昂貴的。不過,您也許可以使用cleanUp()方法確保size不會意外計算已悄悄驅逐的條目。

我不會取決於在這給你確切的結果,但它應該顯着提高結果的準確性。

+0

'size()'之前的'cleanUp()'訣竅!謝謝。我已經搞混了一個基於Esper的解決方案,我仍在測試。我要麼接受這個答案,要麼提供我自己的答案,取決於哪個解決方案更容易/更好。 – hgus1294 2012-02-23 16:23:52

0

我還沒有使用它,但它看起來像this可能會滿足你的需要

+3

從番石榴10.0(2011年9月28日發佈)開始,許多MapMaker方法已被棄用,以支持新的CacheBuilder,這是我一直在測試而沒有成功的。 – hgus1294 2012-02-23 13:48:26

1

我認爲Guava收集與最接近的功能,你想要的是MinMaxPriorityQueue與有限的最大尺寸。您必須按時間順序放置故障事件,並定期檢查第一個元素和最後一個元素之間的差異以及是否已滿。

但你基本上想要的是一米。您可以從Coda Hale的指標庫中嘗試this Meter

+0

非常感謝,但我認爲使用路易斯提供的解決方案的Guava「緩存」更適合我,因爲我不需要自己處理監控。 – hgus1294 2012-02-23 16:33:41

1

你可以裝飾一個集合實現來做到這一點。像這樣:

public class ExpirableArrayList<E> extends ArrayList<E> { 

    private final Date creation = new Date(); 

    private final long timeToLiveInMs; 

    public ExpirableArrayList(long timeToLiveInMs, int initialCapacity) { 
     super(initialCapacity); 
     this.timeToLiveInMs = timeToLiveInMs; 
    } 

    public ExpirableArrayList(long timeToLiveInMs) { 
     this.timeToLiveInMs = timeToLiveInMs; 
    } 

    public ExpirableArrayList(long timeToLiveInMs, Collection<? extends E> c) { 
     super(c); 
     this.timeToLiveInMs = timeToLiveInMs; 
    } 

    private void expire() { 
     if (System.currentTimeMillis() - creation.getTime() > timeToLiveInMs) { 
      clear(); 
     } 
    } 

    @Override 
    public int size() { 
     expire(); 
     return super.size(); 
    } 

    @Override 
    public boolean isEmpty() { 
     expire(); 
     return super.isEmpty(); 
    } 

    @Override 
    public boolean contains(Object o) { 
     expire(); 
     return super.contains(o); 
    } 

    @Override 
    public Iterator<E> iterator() { 
     expire(); 
     return super.iterator(); 
    } 

    @Override 
    public Object[] toArray() { 
     expire(); 
     return super.toArray(); 
    } 

    @Override 
    public <T> T[] toArray(T[] a) { 
     expire(); 
     return super.toArray(a); 
    } 

    @Override 
    public boolean add(E e) { 
     expire(); 
     return super.add(e); 
    } 

    @Override 
    public boolean remove(Object o) { 
     expire(); 
     return super.remove(o); 
    } 

    @Override 
    public boolean containsAll(Collection<?> c) { 
     expire(); 
     return super.contains(c); 
    } 

    @Override 
    public boolean addAll(Collection<? extends E> c) { 
     expire(); 
     return super.addAll(c); 
    } 

    @Override 
    public boolean addAll(int index, Collection<? extends E> c) { 
     expire(); 
     return super.addAll(index, c); 
    } 

    @Override 
    public boolean removeAll(Collection<?> c) { 
     expire(); 
     return super.removeAll(c); 
    } 

    @Override 
    public boolean retainAll(Collection<?> c) { 
     expire(); 
     return super.retainAll(c); 
    } 

    @Override 
    public E get(int index) { 
     expire(); 
     return super.get(index); 
    } 

    @Override 
    public E set(int index, E element) { 
     expire(); 
     return super.set(index, element); 
    } 

    @Override 
    public E remove(int index) { 
     expire(); 
     return super.remove(index); 
    } 

    @Override 
    public int indexOf(Object o) { 
     expire(); 
     return indexOf(o); 
    } 

    @Override 
    public int lastIndexOf(Object o) { 
     expire(); 
     return lastIndexOf(o); 
    } 

    @Override 
    public ListIterator<E> listIterator() { 
     expire(); 
     return listIterator(); 
    } 

    @Override 
    public ListIterator<E> listIterator(int index) { 
     expire(); 
     return listIterator(); 
    } 

    @Override 
    public List<E> subList(int fromIndex, int toIndex) { 
     expire(); 
     return subList(fromIndex, toIndex); 
    } 
}