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