簡體   English   中英

Netty 服務器關閉期間的異常

[英]Exception during Netty server shutdown

我有應用程序在 Tomcat 上運行。 我使用 Netty 4 進行 websocket 處理。 Netty 服務器在 ServletContextListener 中的 contextInitialized 方法中運行,並在 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 時出現異常:

信息:非法訪問:此 Web 應用程序實例已停止。 無法加載 io.netty.util.concurrent.DefaultPromise$3。 最終的后續堆棧跟蹤是由出於調試目的拋出的錯誤以及嘗試終止導致非法訪問的線程引起的,並且沒有功能影響。 java.lang.IllegalStateException at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1610) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1569) at io.netty.util。 concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:592) at io.netty.util.concurrent.DefaultPromise.setSuccess(DefaultPromise.java:403) at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:139) ) 在 java.lang.Thread.run(Thread.java:662)

Tomcat掛斷后。 什么可以是原因?

我假設您從 Servlet.destroy shutdownWorkers()某處調用shutdownWorkers()或使用其他一些機制來確保您的服務器在 servlet 停止/卸載時關閉。

然后你需要做

void shutdownWorkers() {
    Future fb = trbossGroup.shutdownGracefully();
    Future fw = workerGroup.shutdownGracefully();
    try {
        fb.await();
        fw.await();
    } catch (InterruptedException ignore) {}
}

這是因為shutdownGracefully()返回一個Future,而且,不用等待它的到來,你就會在壓力很大的環境中嘗試關閉連接。 首先啟動所有關閉,然后等待期貨可用也是有意義的,這樣它就可以並行運行並且發生得更快。

它為我解決了這個問題。 顯然,您可以讓它對您的系統更好,而無需吞下 InterruptedException並將每個調用包裝在一個很好的方法中,並為每個await()設置合理的超時。 總體來說不錯的練習,但實際上很可能你不會在意你的代碼。

旁注:是的,對於 WebSockets,使用 Tomcat 的原生、符合標准和健壯的實現會更好。 Netty 在許多其他方面都很棒,但在這里是一個錯誤的工具。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM