我的系统中有3个ThreadPoolExecutors。
一个用于Netty的主进程,另一个用于netty的工作进程,另一个用于处理临时处理(向邮件服务器发送请求)。
ExecutorService bossExecutors = Executors.newFixedThreadPool(1, new
ServerThreadFactory("netty-boss")); ExecutorService workerExecutors =
Executors.newFixedThreadPool(10, new
ServerThreadFactory("netty-worker"));
ChannelFactory factory = new NioServerSocketChannelFactory(
bossExecutors,
workerExecutors,
Runtime.getRuntime().availableProcessors());
ExecutorService mailExecutor = Executors.newFixedThreadPool(40);
在mailExecutor
开始向邮件服务器发出请求之前,此工作完全正常。直到该批量请求使用mailExecutor
,通常会对邮件服务器发出5000多个请求,netty线程被阻止。
我不明白为什么netty线程似乎被阻塞了,因为我已经分配了明确的线程池。在此期间,Netty甚至无法处理单个请求。
知道为什么会这样,或者我做错了什么?
感谢。
答案 0 :(得分:1)
你能提供一个线程转储吗?
jstack <pid>
此外,您永远不应该使用固定的线程池作为worker / poss线程池。使用缓存的方式,这样你就可以确保永远不会陷入任何饥饿状态。您应该在构造函数中使用3参数指定worker count。
答案 1 :(得分:0)
这听起来像是一个调度问题。重负载下有40个线程,而处理Netty工作的可用线程数是多少(在创建工厂时你的availableProcessors()数是多少?)。
因此,可能只是因为Netty线程太少而且正在挨饿,因为与处理邮件工作的40个线程相比,它们从未被选中执行。
也可能是由于某种原因,你的工作线程被阻塞在邮件线程上完成,可能是由于某些正在同步的共享对象(是否有一些队列或要发送的邮件列表,netty线程需要写入,以及邮件线程在发送时锁定了哪些?)。