簡體   English   中英

您能以編程方式更改Java嵌入式代理中隊列的“死信”處理嗎?

[英]Can you programmatically alter a queue's “dead letter” handling in a Java embedded broker?

背景

在高級別,我有一個Java應用程序,其中某些事件應該觸發當前用戶采取的某個操作。 但是,事件可能非常頻繁,並且操作始終相同。 因此,當第一個事件發生時,我想在不久的將來安排行動(例如5分鍾)。 在該時間窗口期間,后續事件不應采取任何操作,因為應用程序發現已經安排了操作。 一旦計划的操作執行,我們將返回步驟1,下一個事件將再次開始循環。

我的想法是通過在應用程序本身內嵌入內存中的ActiveMQ實例來實現這種過濾和限制機制(我不關心隊列持久性)。

我相信JMS 2.0支持延遲傳送的概念,延遲消息位於“暫存隊列”中,直到傳送到真實目的地為止。 但是,我也相信ActiveMQ還不支持JMS 2.0規范......所以我正在考慮模仿生存時間(TTL)值和死信隊列(DLQ)處理的相同行為。

基本上,我的消息生成器代碼會將消息放在虛擬登台隊列上,消費者從中沒有任何東西 消息將以5分鍾的TTL值放置,並在到期時ActiveMQ將它們轉儲到DLQ中。 這是我的消息消費者實際消費消息的隊列。

我認為我不想實際使用“默認”DLQ,因為我不知道ActiveMQ可能會在那里轉儲哪些與我的應用程序代碼完全無關的內部事物。 所以我認為我的虛擬登台隊列最好有自己的自定義DLQ。 我只看過一頁討論DLQ配置的ActiveMQ文檔,它只針對獨立的ActiveMQ安裝(不是嵌入在應用程序中的內存代理)的XML配置文件。

是否可以在運行時以編程方式為嵌入式ActiveMQ實例中的隊列配置自定義DLQ?

如果你認為我走錯了路,我也有興趣聽聽其他建議。 我對JMS比AMQP更熟悉,所以我不知道Qpid或其他一些Java嵌入式AMQP代理是否更容易。 無論Apache Camel究竟是什么(!),我相信它應該在這類事情上表現出色,但這種學習曲線對於這個用例來說可能是徹底的過度殺傷力。

雖然你擔心Camel對於這個用例可能是一個嚴重的過度殺傷,但我認為ActiveMQ對於你所描述的用例來說已經嚴重過度。

您希望在事件發生5分鍾后安排事情發生,並且只消耗第一個事件並忽略第一個事件和5分鍾之間的所有事件,對嗎? 為什么不從現在開始通過ScheduledExecutorService或您喜歡的調度機制安排處理方法5分鍾,並將事件保存在HashMap<User, Event>成員變量中。 如果在處理方法觸發之前有更多事件進入該用戶,您將看到已經存儲了一個事件而沒有存儲新事件,因此您將忽略除第一個之外的所有事件。 在處理方法結束時,從HashMap刪除此用戶的事件,然后將存儲和計划下一個要進入的事件。

運行ActiveMQ只是為了獲得這種行為似乎比你需要的更多。 如果沒有,你能解釋一下原因嗎?

編輯:

如果您沿着這條路走下去,請不要使用消息TTL來使您的消息過期; 讓(唯一的)消費者將它們讀入內存並使用上述內存解決方案僅每5分鍾處理一次(最多)一批。 要么具有帶有消息選擇器的單個隊列,要么使用動態隊列,每個用戶一個。 你不需要DLQ來實現延遲,即使你可以做到這一點,它也不會給你批處理所有功能,所以你每5分鍾只運行一次。 這不是你想要貶低的道路,即使你弄清楚如何。

一個簡單的解決方案是跟蹤並發結構中的掛起操作,並使用ScheduledExecutorService來執行它們:

private static final Object RUNNING = new Object();
private final ConcurrentMap<UserId, Object> pendingActions = 
    new ConcurrentHashMap<>();
private ScheduledExecutorService ses = Executors.newScheduledThreadPool(10);


public void takeAction(final UserId id) {
    Object running = pendingActions.putIfAbsent(id, RUNNING);  // atomic
    if(running == null) {                // no pending action for this user
        ses.schedule(new Runnable() {
            @Override
            public void run() {
                doWork();
                pendingActions.remove(id);
            }
        }, 5, TimeUnit.MINUTES);
    }
}

使用Camel可以使用帶有參數completionIntervalAggregator組件輕松實現,因此每隔五分鍾就可以檢查列表聚合消息是否為空,如果它沒有向負責用戶操作的路由發送消息並清空列表。 您確實需要維護整個交換列表,只需要維護狀態(計划用戶行為與否)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM