【发布时间】:2014-07-17 23:54:21
【问题描述】:
我有在 Tomcat 上运行的应用程序。我使用 Netty 4 进行 websocket 处理。 Netty 服务器在 contextInitialized 方法中运行在 ServletContextListener 中,并在 contextDestroyed 中停止。
这是我的 Netty 服务器类:
public class WebSocketServer {
private final int port;
private final EventLoopGroup bossGroup;
private final EventLoopGroup workerGroup;
private Channel serverChannel;
public WebSocketServer(int port) {
this.port = port;
bossGroup = new NioEventLoopGroup(1);
workerGroup = new NioEventLoopGroup();
}
public void run() throws Exception {
final ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
.childHandler(new WebSocketServerInitializer());
serverChannel = b.bind(port).sync().channel();
System.out.println("Web socket server started at port " + port + '.');
System.out
.println("Open your browser and navigate to http://localhost:"
+ port + '/');
}
public void stop() {
if (serverChannel != null) {
ChannelFuture chFuture = serverChannel.close();
chFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
shutdownWorkers();
}
});
} else {
shutdownWorkers();
}
}
private void shutdownWorkers() {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
运行后一切正常,但是当我尝试停止 Tomcat 时出现异常:
INFO:非法访问:此 Web 应用程序实例已被停止。无法加载 io.netty.util.concurrent.DefaultPromise$3。最终的后续堆栈跟踪是由出于调试目的引发的错误以及试图终止导致非法访问的线程引起的,并且没有功能影响。 java.lang.IllegalStateException 在 org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1610) 在 org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1569) 在 io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:592) 在 io.netty.util.concurrent.DefaultPromise.setSuccess(DefaultPromise.java:403) 在 io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:139) 在 java.lang.Thread.run(Thread.java:662)
Tomcat 挂断后。 可能是什么原因?
【问题讨论】:
-
shutdown-methods 通知线程停止,但可能不会等待所有线程完成。与此同时,Tomcat 继续关闭 webapp 和 webapp 中仍在运行的线程,出现错误,因为除其他外,Tomcat 卸载了 webapp 加载的所有类。
-
谢谢,是有原因的。现在我使用 awaitTermination 来完成关机。并且Tomcat无一例外地停止正常。但它会在日志中写入下一条消息:Web 应用程序 [/MySite] 似乎已经启动了一个名为 [nioEventLoopGroup-3-2] 的线程,但未能停止它。这很可能造成内存泄漏。什么可能导致这种泄漏?
-
这意味着一个线程没有停止运行并将webapp加载的类保存在内存中,因此内存使用量会随着webapp的每次重新部署而增加。但是你知道Tomcat支持websocketsnatively吗? IE。你不需要 Netty。
-
我遇到了类似的问题并发布了解决方案。