簡體   English   中英

如何可靠地殺死服務器之間的@Scheduled線程?

[英]How to reliably kill @Scheduled threads across servers?

我正在構建一個實現為Spring MVC應用程序的插件。 該插件通過其中一台服務器上的gui部署在3-6台tomcat服務器上。 插件的每個實例都有一個@Scheduled方法,以收集服務器上的信息並將其存儲在中央數據庫中。

我的問題是,用於卸載插件的gui接口使某些@Scheduled線程處於運行狀態。

例如,我有一個具有服務器1-3的環境。我通過服務器1上的gui安裝並啟用了插件。現在在服務器1-3上有3個運行@Scheduled線程的應用程序實例。服務器1並卸載插件,該線程將在服務器1上可靠地殺死,但在服務器2或3上則不會被殺死。

我實現了以下內容,但該行為仍然存在:

@Component
public class ContextClosedListener implements ApplicationListener<ContextClosedEvent> {
    @Autowired 
    ThreadPoolTaskExecutor executor;

    @Autowired 
    ThreadPoolTaskScheduler scheduler;

    public void onApplicationEvent(ContextClosedEvent event) {
        scheduler.shutdown();
        executor.shutdown();
    }  
}

另外,我曾考慮將其實現為上下文偵聽器,而不是@Scheduled方法,但出於維護和可擴展性的原因,我寧願堅持使用Spring。

如何在這樣的環境中可靠地殺死線程?

我有幾個想法。 ThreadPoolTask​​Executor有一個方法setThreadNamePrefix,它允許您設置線程的前綴。 您可以將前綴設置為唯一的前綴,然后在運行時查找並殺死那些線程。 您還可以在同一對象上使用setThreadGroup方法設置線程組,然后僅停止線程組中的線程。

更好,更安全的解決方案是在計划的作業中創建突破方法。 這是停止Thread的首選方法,而不是調用Thread.stop()的舊的“將其射入頭部”方法。 您可以通過設置公共前綴或使用如上所述的線程組來引用那些Runnable。

下一個問題是:如何輕松停止線程? 為此,這取決於您的應用程序是如何實現的。 由於我主要處理Spring MVC應用程序,因此我的第一個解決方案是編寫一個Controller來處理管理任務。 如果這是JBoss或其他具有JMX的大型應用服務器(我相信Tomcat可以配置為提供JMX,但我認為這樣配置不是開箱即用的),則可以編寫一個啟用JMX的bean來請允許我通過應用服務器控制台停止線程。 基本上,給自己一個觸發線程停止的方法。

暫無
暫無

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

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