簡體   English   中英

消息驅動的Bean和超時中長時間運行的任務

[英]Long running tasks in message-driven beans and timeouts

我想使用MDB(小時)來處理一些運行時間很長的任務,但是MDB是由JMS支持的,它有一些超時(我認為在tomEE中大約需要10分鍾)。

更糟糕的是,工作也是持久的。

由於我無法在MDB上捕獲超時異常(可以嗎?),因此我正在考慮手動處理JMS使用者的選項。 可以通過兩種方式手動處理它:同步或異步。

異步地,我將回退到實現MessageListener的無狀態bean,然后我將無法再次處理超時。

我想,可以同步地在catch塊中處理超時,但是,如何在TomEE +中實現一個實例/工人/對象池,這些實例/工人/對象正在監聽隊列,等待作業處理? (請記住,此處的超時不是等待消息出現在隊列中的時間,而是執行長時間運行的任務的時間)

嘗試將消耗性的JMS消息和長時間運行的處理任務分開

MDB可以從隊列中獲取消息並使用異步方法調用來調用無狀態會話Bean

為什么不將長期運行的過程分叉到一個單獨的對象上呢? >如果有一種方法可以控制這些單獨對象的池大小,則可能是一種方法。 您想嘗試答案嗎? :-)

您不希望對象隨時間增長嗎? 嗯...我可以看到你要去哪里。

我唯一想到的就是在並發框架中使用FixedThreadPool。 生成用於執行長時間運行任務的線程,並確保MDB在移交工作后立即返回。 通過在測試環境中對應用程序進行性能分析來控制線程池。

諸如Weblogic和Websphere之類的應用服務器為您提供了諸如WorkManager之類的復雜框架來執行此類任務。

JEE7中存在ManagedExecutorService來處理異步任務的執行。 通過利用Future接口實現(請參閱FutureTask ),也可以使任務可取消。 以下內容僅作為示例,請勿1:1復制並在生產中使用。 UUID永遠不會清除它在未來的地圖中發生內存泄漏。

import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;
import java.util.concurrent.RunnableFuture;

import javax.annotation.Resource;
import javax.enterprise.concurrent.ManagedExecutorService;
import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class AsyncTaskManager {

    @Resource
    private ManagedExecutorService mes;

    private Map<String, Future> futureByUUID = new ConcurrentHashMap<>();

    /**
     * Launch the provided Future implemented task.
     * @param runnable The runnable implementation to execute.
     * @param <R> The type of the task result returned.
     * @return The UUID that the executing ask is mapped to.
     */
    public <R> String launch (RunnableFuture<R> runnable) {
        String uuid = UUID.randomUUID().toString();
        mes.submit(runnable);
        futureByUUID.put(uuid, runnable);
        return uuid;
    }

    /**
     * Retrieve a future instance by it's UUID.
     * @param uuid The uuid of the future.
     * @param <T> The type of the future's result.
     * @return The future instance.
     */
    @SuppressWarnings("unchecked")
    public <T> Future<T> getByUUID (String uuid) {
        return (Future<T>)futureByUUID.get(uuid);
    }
}

可以結合使用一整套接口和類來更改執行程序服務中任務的行為。 例如, ManagedTask接口提供對其中某些行為的訪問。

@Asynchronous的答案中提到了ManagedExecutorService用於@Asynchronous EJB方法注釋。 任務創建和Future實例創建由EJB框架處理。

暫無
暫無

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

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