Netty DefaultEventExecutorGroup线程持续增长,服务器对请求的响应速度较慢
我正在使用Netty-4.1.0-Beta5,我正在使用DefaultEventExecutorGroup(带2个线程)作为长时间运行的处理程序(以解除阻止I/O线程),在运行服务器几个小时后,我看到大约2155个组,每个组有1个线程Netty DefaultEventExecutorGroup线程持续增长,服务器对请求的响应速度较慢,netty,Netty,我正在使用Netty-4.1.0-Beta5,我正在使用DefaultEventExecutorGroup(带2个线程)作为长时间运行的处理程序(以解除阻止I/O线程),在运行服务器几个小时后,我看到大约2155个组,每个组有1个线程 defaultEventExecutorGroup-10-1 tid=134 [WAITING] sun.misc.Unsafe.park(boolean, long) Unsafe.java java.util.concurrent.locks.LockSup
defaultEventExecutorGroup-10-1 tid=134 [WAITING]
sun.misc.Unsafe.park(boolean, long) Unsafe.java
java.util.concurrent.locks.LockSupport.parkNanos(Object, long) LockSupport.java:215
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(long) AbstractQueuedSynchronizer.java:2078
java.util.concurrent.LinkedBlockingQueue.poll(long, TimeUnit) LinkedBlockingQueue.java:467
io.netty.util.concurrent.SingleThreadEventExecutor.takeTask() SingleThreadEventExecutor.java:194
io.netty.util.concurrent.DefaultEventExecutor.run() DefaultEventExecutor.java:54
io.netty.util.concurrent.SingleThreadEventExecutor$4.run() SingleThreadEventExecutor.java:703
io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run() DefaultThreadFactory.java:137
java.lang.Thread.run() Thread.java:745
大多数HTTP请求的响应时间都超过20秒,下面是我的代码:
class NettyServer extends Logging {
val allChannels = new DefaultChannelGroup("enter", GlobalEventExecutor.INSTANCE)
val webSocketConnections = new WebSocketConnections("websockets")
val sslManager: Option[SslManager] = Some(new SslManager(this))
def start(): Unit = {
allChannels.clear()
val bootstrap = new ServerBootstrap()
bootstrap.group(new NioEventLoopGroup(), new NioEventLoopGroup())
bootstrap.channel(classOf[NioServerSocketChannel])
bootstrap.childOption[java.lang.Boolean](ChannelOption.TCP_NODELAY, true)
bootstrap.childHandler(new PipelineFactory(this))
val bindFutures = "0.0.0.0".split(",").map(address => {
address.trim match
case "0.0.0.0" =>
bootstrap.bind(9999)
case _ if (!address.isEmpty) =>
bootstrap.bind(address, 9999)
})
allChannels.addAll(bindFutures.map(_.channel).toList)
val latch = new CountDownLatch(bindFutures.length)
val bindFutureListener = new ChannelFutureListener {
def operationComplete(future: ChannelFuture) = {
latch.countDown
}
}
bindFutures.foreach(_.addListener(bindFutureListener))
latch.await
}
def stop(): Unit = {
val future = allChannels.close()
future.awaitUninterruptibly()
allChannels.clear()
}
}
class PipelineFactory(server: NettyServer) extends ChannelInitializer[SocketChannel] with Logging {
override def initChannel(ch: SocketChannel) {
val pipeline = ch.pipeline
pipeline.addLast("ssl", new SslHandler(server.sslManager.get.createSSLEngine()))
pipeline.addLast("httpRequestDecoder", new HttpRequestDecoder(4096, 8192, 8192, false))
pipeline.addLast("httpResponseEncoder", new HttpResponseEncoder())
pipeline.addLast("chunkAggregator", new HttpObjectAggregator(65536))
pipeline.addLast("idleStateHandler", new IdleStateHandler(0, 0, 0))
val corsConfig = CorsConfig.withAnyOrigin()
pipeline.addLast("corsHandler", new CorsHandler(corsConfig))
pipeline.addLast(new DefaultEventExecutorGroup(2), "handler", new MyHandler())
}
}
你知道我的代码有什么问题吗?如果我使用curl在紧循环中发送10000个HTTP请求,那么我可以重新创建这个问题。
谢谢你的帮助 只需创建一次DefaultEventExecutorGroup并共享实例。在为每个频道创建时,我认为这里的问题是管道.addLast(新的DefaultEventExecutorGroup(2),“handler”,new MyHandler())为每个新频道创建新的
DefaultEventExecutorGroup
,我只需要创建DefaultEventExecutorGroup的一个实例。
class NettyServer extends Logging {
val allChannels = new DefaultChannelGroup("enter", GlobalEventExecutor.INSTANCE)
val webSocketConnections = new WebSocketConnections("websockets")
val sslManager: Option[SslManager] = Some(new SslManager(this))
def start(): Unit = {
allChannels.clear()
val bootstrap = new ServerBootstrap()
bootstrap.group(new NioEventLoopGroup(), new NioEventLoopGroup())
bootstrap.channel(classOf[NioServerSocketChannel])
bootstrap.childOption[java.lang.Boolean](ChannelOption.TCP_NODELAY, true)
bootstrap.childHandler(new PipelineFactory(this))
val bindFutures = "0.0.0.0".split(",").map(address => {
address.trim match
case "0.0.0.0" =>
bootstrap.bind(9999)
case _ if (!address.isEmpty) =>
bootstrap.bind(address, 9999)
})
allChannels.addAll(bindFutures.map(_.channel).toList)
val latch = new CountDownLatch(bindFutures.length)
val bindFutureListener = new ChannelFutureListener {
def operationComplete(future: ChannelFuture) = {
latch.countDown
}
}
bindFutures.foreach(_.addListener(bindFutureListener))
latch.await
}
def stop(): Unit = {
val future = allChannels.close()
future.awaitUninterruptibly()
allChannels.clear()
}
}
class PipelineFactory(server: NettyServer) extends ChannelInitializer[SocketChannel] with Logging {
override def initChannel(ch: SocketChannel) {
val pipeline = ch.pipeline
pipeline.addLast("ssl", new SslHandler(server.sslManager.get.createSSLEngine()))
pipeline.addLast("httpRequestDecoder", new HttpRequestDecoder(4096, 8192, 8192, false))
pipeline.addLast("httpResponseEncoder", new HttpResponseEncoder())
pipeline.addLast("chunkAggregator", new HttpObjectAggregator(65536))
pipeline.addLast("idleStateHandler", new IdleStateHandler(0, 0, 0))
val corsConfig = CorsConfig.withAnyOrigin()
pipeline.addLast("corsHandler", new CorsHandler(corsConfig))
pipeline.addLast(new DefaultEventExecutorGroup(2), "handler", new MyHandler())
}
}