SelectorImpl is BLOCKED(SelectorImpl被阻止)
本文介绍了SelectorImpl被阻止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我用很多客户端向服务器发送一个请求,每秒大约1000个请求一个客户端,服务器的CPU很快就上升到600%(8核),并始终保持这种状态。当我使用jSTACK打印处理内容时,我发现SelectorImpl处于阻塞状态。记录如下:nioEventLoopGroup-4-1 prio=10 tid=0x00007fef28001800 nid=0x1dbf waiting for monitor entry [0x00007fef9eec7000]
java.lang.Thread.State: BLOCKED (on object monitor)
at sun.nio.ch.EPollSelectorImpl.doSelect(Unknown Source)
- waiting to lock <0x00000000c01f1af8> (a java.lang.Object)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(Unknown Source)
- locked <0x00000000c01d9420> (a io.netty.channel.nio.SelectedSelectionKeySet)
- locked <0x00000000c01f1948> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000000c01d92c0> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(Unknown Source)
at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:635)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:319)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101)
at java.lang.Thread.run(Unknown Source)
高CPU与此有关吗?另一个问题是,当我连接很多客户端时,发现有一些客户端会连接,错误如下:
"nioEventLoopGroup-4-1" prio=10 tid=0x00007fef28001800 nid=0x1dbf waiting for monitor entry [0x00007fef9eec7000]
java.lang.Thread.State: BLOCKED (on object monitor)
at sun.nio.ch.EPollSelectorImpl.doSelect(Unknown Source)
- waiting to lock <0x00000000c01f1af8> (a java.lang.Object)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(Unknown Source)
- locked <0x00000000c01d9420> (a io.netty.channel.nio.SelectedSelectionKeySet)
- locked <0x00000000c01f1948> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000000c01d92c0> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(Unknown Source)
at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:635)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:319)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101)
at java.lang.Thread.run(Unknown Source)
生成客户端是使用线程池完成的,并且已经设置了连接超时,但为什么频繁连接超时?是为了诉讼的目的吗?
public void run() {
System.out.println(tnum + " connecting...");
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 30000)
.handler(loadClientInitializer);
// Start the connection attempt.
ChannelFuture future = bootstrap.connect(host, port);
future.channel().attr(AttrNum).set(tnum);
future.sync();
if (future.isSuccess()) {
System.out.println(tnum + " login success.");
goSend(tnum, future.channel());
} else {
System.out.println(tnum + " login failed.");
}
} catch (Exception e) {
XLog.error(e);
} finally {
//group.Shutdown Gractily(); )
}
推荐答案
高CPU与此有关?
可能是。我会通过以下方式诊断这个问题(在Linux机器上):
查找占用CPU的线程
使用pidstat
我可以找出哪些线程在消耗CPU,以及以什么模式(用户/内核)花费时间。
$ pidstat -p [java-process-pid] -tu 1 | awk '$9 > 50'
此命令显示线程占用了至少50%的CPU时间。您可以使用jstack
、VisualVM或Java飞行记录器检查这些线程正在执行的操作。
如果占用大量CPU的线程和被阻止的线程相同,则CPU使用率似乎与争用有关。
查找连接超时的原因
基本上,如果两个操作系统无法在给定时间内完成TCP握手,您将获得连接超时。这有几个原因:- 网络链路饱和。可以使用
sar -n DEV 1
进行诊断,并将rxkB/s
和txkB/s
列与您的链路最大吞吐量进行比较。 - 服务器(Netty)在给定的超时时间内未响应
accept()
调用。此线程可能会被阻塞或占用CPU时间。您可以使用strace -f -e trace=accept -p [java-pid]
找出哪些线程正在调用accept()
(因此完成了tcp握手)。然后使用pidstat
/jstack
检查可能的原因。
您还可以使用netstat -an | grep -c SYN_RECV
这篇关于SelectorImpl被阻止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
织梦狗教程
本文标题为:SelectorImpl被阻止


基础教程推荐
猜你喜欢
- 使用堆栈算法进行括号/括号匹配 2022-01-01
- 存储 20 位数字的数据类型 2022-01-01
- REST Web 服务返回 415 - 不支持的媒体类型 2022-01-01
- 修改 void 函数的输入参数,然后读取 2022-01-01
- Spring AOP错误无法懒惰地为此建议构建thisJoinPoin 2022-09-13
- 问题http://apache.org/xml/features/xinclude测试日志4j 2 2022-01-01
- RabbitMQ:消息保持“未确认"; 2022-01-01
- 无法复制:“比较方法违反了它的一般约定!" 2022-01-01
- Struts2 URL 无法访问 2022-01-01
- 如何对 Java Hashmap 中的值求和 2022-01-01