如何实时获取执行器的队列大小

zd1*_*d14 6 java spring asynchronous spring-boot

假设我有这个application.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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的目标是,如果异步执行器的当前实时队列大小达到 80% 或接近限制,则创建警报。我认为我们可以从中获得价值executor.getThreadPoolExecutor().getQueue().size();。我目前陷入了如何实现这一目标的困境

Kay*_*man 5

@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();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您可以将 bean 提供为 a ThreadPoolExecutor,那么您甚至不需要强制转换。size()in LinkedBlockingQueue(ThreadPoolExecutor 使用的)的内部实现是AtomicInteger.get()

因此,无需发挥创意并建立自己的机制,一切都是内置的。基于 Spring 4.2,但不应过多依赖版本。


因此,根本目标是监视队列,并在队列已满 80% 时发送警报。这不应该进入您负责确保业务逻辑正常工作的代码中。你不应该因为缺乏资源而在那里进行黑客攻击。如果您的想法是在队列拥挤时应该限制用户,那么有更好的方法来处理这些问题。

由于我们的想法是进行“轻度监控”,即不会尝试处理队列已满 80% 的情况,因此轮询解决方案将足够轻量。考虑到执行器可以轻松地注入到单独的 中Controller,它甚至不会弄乱您的“真实”代码。