[英]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.