zoukankan      html  css  js  c++  java
  • Netty-主动关闭Server

      工作中要能主动地关闭netty server端,下面的文章中的方法是好用的,记录一下。

      原文地址:https://blog.csdn.net/wk52525/article/details/87896075

      1.主动关闭server

    • 如下面的代码所示,这里启动server时将ServerChannel的实例保存至静态属性,然后暴露一个closeServer()方法,直接调用ServerChannel的close()方法,此线程则会从阻塞状态恢复,向下执行,进入finally代码块,退出server并清理相关资源。
    package com.huoli.mj.rpc.server;
     
    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.Channel;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelOption;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.nio.NioServerSocketChannel;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
     
    public class NettyServer {
     
        private static Logger logger = LoggerFactory.getLogger(NettyServer.class);
        
        private static Channel serverChannel;
     
        /** 关闭当前server */
        public static void closeServer() {
            if (serverChannel != null) {
                logger.info("close server");
                serverChannel.close();
                serverChannel = null;
            }
        }
     
        /** 启动server */
        private void start(int port) throws Exception {
            // 通过独立线程启动server
            Thread nettyServer = new Thread(() -> {
                EventLoopGroup bossGroup = new NioEventLoopGroup();
                EventLoopGroup workerGroup = new NioEventLoopGroup();
                try {
                    ServerBootstrap b = new ServerBootstrap();
                    b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                            .childHandler(new DefaultServerChannelInitializer()).option(ChannelOption.SO_BACKLOG, 128)
                            .childOption(ChannelOption.SO_KEEPALIVE, true);
     
                    // 绑定端口启动成功
                    ChannelFuture channelFuture = b.bind(port).sync();
                    logger.info("start rpc server success with port:" + port);
                    // 将ServerChannel保存下来
                    serverChannel = channelFuture.channel();
                    // 阻塞至channel关闭
                    serverChannel.closeFuture().sync();
                } catch (Exception e) {
                    logger.error("MJ netty server error", e);
                } finally {
                    // 优雅关闭server线程及相关资源
                    workerGroup.shutdownGracefully();
                    bossGroup.shutdownGracefully();
                }
            });
            nettyServer.setName("netty-server-thread");
            nettyServer.setDaemon(true);
            nettyServer.start();
        }
    }

      2.在ChannelHandler中关闭server

    • 在某些场景下,会需要在特定事件回调时主动关闭server端。下面代码展示了在监听到异常抛出事件时主动关闭server的操作。
    • 以下面代码为例:ChannelHandler的事件回调方法中,ctx.close() 或 ctx.channel().close()只能关闭与某个客户端连接的channel,而ctx.channel().parent()获取到的是ServerChannel,所以调用ctx.channel().parent().close()才能关闭server,使server启动线程从阻塞状态恢复,从而在finally代码块中执行退出关闭操作。
    package top.kylewang.netty.demo.second.server;
     
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
     
    public class TestSocketServerHandler extends ChannelInboundHandlerAdapter {
     
        private static final Logger logger = LoggerFactory.getLogger(TestSocketServerHandler.class);
     
        /** 监听异常 */
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            cause.printStackTrace();
            // 关闭serverChannel
            ctx.channel().parent().close();
        }
  • 相关阅读:
    凹透镜
    三角形动点和将军饮马
    数学
    壮壮学习准则
    均值不等式,求极值
    2020年自贡中考数学真题,用的是花钱买的"几何画板",wechat:QZCS12
    90年高考题
    裂项:2005年初中数学竞赛题p32,4
    02-需求来源
    01-产品需求的内涵
  • 原文地址:https://www.cnblogs.com/lnlvinso/p/14208887.html
Copyright © 2011-2022 走看看