簡體   English   中英

如何實時獲取executor的隊列大小

[英]How to get the queue size of the executor in real time

假設我有這個application.java 。java

@SpringBootApplication
public class Application {
    public static void main(String[] args){
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public Executor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(50);
        executor.setMaxPoolSize(100);
        executor.setQueueCapacity(5000);
        executor.setThreadNamePrefix("sm-async-");
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.initialize();
        return executor;
    }
}

我的目標是在異步執行器的當前實時隊列大小在 80% 或接近限制時創建警報。 我認為我們可以從executor.getThreadPoolExecutor().getQueue().size(); . 我目前堅持如何實現這一目標

@Controller
public class QueueMonitorController {

    @Autowired
    private Executor executor;

    @RequestMapping(value = "/queuesize", method = RequestMethod.GET)
    public int queueSize() {
        ThreadPoolExecutor tpe = (ThreadPoolExecutor)executor;
        return tpe.getQueue().size();
    }
}

如果您可以將 bean 作為ThreadPoolExecutor提供,那么您甚至不需要演員表。 LinkedBlockingQueue (ThreadPoolExecutor 使用)中size()的內部實現是AtomicInteger.get()

所以沒有必要發揮創造力並建立自己的機制,這一切都是內置的。 基於 Spring 4.2,但不應過多依賴版本。


所以根本目標是監控隊列,並在隊列滿 80% 時發送警報。 這不應該 go 到您負責確保您的業務邏輯正常工作的代碼中。 你不應該因為缺乏資源而在那里進行黑客攻擊。 如果你的想法是當隊列被擠滿時你應該限制用戶,那么有更好的方法來處理這些。

由於這個想法是做“輕量級監控”,即當隊列已滿 80% 時不會嘗試處理情況,因此輪詢解決方案將足夠輕量級。 考慮到執行器可以很容易地注入到單獨的Controller中,它甚至不會弄亂你的“真實”代碼。

由於ThreadPoolTaskExecutor Executor 沒有公開任何 API 你可以得到它使用的隊列。 但是,您可以自由擴展ThreadPoolTaskExecutor Executor 並創建一個CustomThreadPoolTaskExecutor覆蓋createQueue

public class CustomThreadPoolTaskExecutor extends ThreadPoolTaskExecutor{

    private BlockingQueue<Runnable> queue;

    @Override
    protected BlockingQueue<Runnable> createQueue(int queueCapacity) {
        queue = super.createQueue(queueCapacity);
        return queue;
    }

    public BlockingQueue<Runnable> getQueue(){
      return queue;
    }
}

現在您可以像下面這樣創建asyncExecutor

@Bean
public Executor asyncExecutor() {
    ThreadPoolTaskExecutor executor = new CustomThreadPoolTaskExecutor();
    //set other properties
    executor.initialize();
    return executor;
}

您的CustomThreadPoolTaskExecutor執行程序具有公共方法getQueue ,您可以使用它來獲取隊列。

我不知道你從哪里得到ThreadPoolTaskExecutor Executor class 類型的執行器。 但在 java 中,您可以類型轉換為ThreadPoolExecutor並獲取隊列,其大小如下:

ThreadPoolExecutor executorService =  (ThreadPoolExecutor )Executors.newCachedThreadPool();
        executorService.getQueue().size()

按照您的要求實時執行此操作並不容易。 您需要裝飾BlockingQueue的方法,以便您可以添加代碼以在隊列內容更改時立即執行。

然后,您可以像這樣將隊列提供給 Spring 的ThreadPoolTaskExecutor

ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor() {
  @Override
  protected BlockingQueue<Runnable> createQueue(int queueCapacity) {

    // create and return your instance of blocking queue here
  }
};

暫無
暫無

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

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