面试题答案
一键面试- 关闭新连接接收:
- 使用
ServerBootstrap
启动的服务端,通过Channel
的closeFuture()
方法,先禁止接收新的连接。例如在服务端代码中,可以获取到ServerChannel
,然后调用serverChannel.config().setOption(ChannelOption.SO_ACCEPT, false)
来停止接受新的TCP连接。
- 使用
- 处理现有连接:
- 遍历所有活跃的
Channel
,一般可以通过在ChannelHandler
中维护一个ChannelGroup
(如GlobalChannelGroup
),在连接建立时将Channel
添加到该组中。 - 对每个活跃的
Channel
,调用channel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE)
,这样会将当前缓冲区的数据发送出去,并在发送完成后关闭连接。
- 遍历所有活跃的
- 处理任务队列:
- 如果使用了
EventExecutorGroup
来处理任务,需要调用其shutdownGracefully()
方法。 - 例如
bossGroup.shutdownGracefully()
和workerGroup.shutdownGracefully()
,该方法会等待所有已提交的任务执行完毕,并且不再接受新的任务。可以设置等待任务执行的超时时间,如bossGroup.shutdownGracefully(0, 1, TimeUnit.SECONDS)
,表示最多等待1秒。
- 如果使用了
- 等待关闭完成:
- 对于
EventExecutorGroup
,可以通过awaitTermination()
方法等待其完全关闭。例如bossGroup.awaitTermination(1, TimeUnit.MINUTES)
等待bossGroup
在1分钟内关闭。 - 对于
Channel
的关闭,可以通过channel.closeFuture().sync()
等待Channel
完全关闭。
- 对于
这样就能在Netty框架下实现优雅停机,确保现有连接的数据能正常处理和发送,并且任务队列中的任务也能正常执行完毕。