public class NettyServer implements ServletContextListener {
private static Logger log = Logger.getLogger(NettyServer.class);
/*线程数量不宜设置过高,线程切换非常耗时*/
public static final EventExecutorGroup exec = new DefaultEventExecutorGroup( Runtime.getRuntime().availableProcessors()*2,
(ThreadFactory) r -> {
Thread thread = new Thread(r);
thread.setName("custom-tcp-exec-"+r.hashCode());
return thread;
},
100000,
RejectedExecutionHandlers.reject()
);
//boss线程监听端口,worker线程负责数据读写
public static final EventLoopGroup boss = Epoll.isAvailable()? new EpollEventLoopGroup(1) : new NioEventLoopGroup(1);
public static final EventLoopGroup worker = Epoll.isAvailable()? new EpollEventLoopGroup() : new NioEventLoopGroup();
/**
* 功能描述:omcat服务器启动时,netty启动
* @return void
* @Author: guoliangbo
* @Date: 2019/9/24 13:18
*/
public static void nettyStart(ApplicationContext applicationContext){
// 初始化websocket
WebSocket.setApplicationContext(applicationContext);
// getRedisVal();
try{
// 初始化ServerBootstrap实例, 此实例是netty服务端应用开发的入口
ServerBootstrap bootstrap = new ServerBootstrap();
// 把两个线程组加入进来 初始化的主从"线程池"
bootstrap.group(boss,worker);
// 指定使用NioServerSocketChannel这种类型通道 由于是服务端,故而是NioServerSocketChannel
bootstrap.channel(Epoll.isAvailable()? EpollServerSocketChannel.class : NioServerSocketChannel.class);
// 一定要使用去绑定具体的事件处理器
bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();
pipeline.addLast(new StringDecoder());
pipeline.addLast(new StringEncoder());
//pipeline.addLast(new NettyServerInHandler(applicationContext));
pipeline.addLast(exec, "handler", new NettyServerInHandler(applicationContext));
}
});
// 最大的等待连接数 默认128
bootstrap.option(ChannelOption.SO_BACKLOG,10000);
// 配置子通道也就是SocketChannel的选项
// 我们已经有了应用层的心跳检测机制,也不需要开启此参数
bootstrap.childOption(ChannelOption.SO_KEEPALIVE,false);
bootstrap.childOption(ChannelOption.TCP_NODELAY,false);
//bootstrap.childOption(ChannelOption.SO_RCVBUF,1024 * 4);
//bootstrap.childOption(ChannelOption.SO_SNDBUF,1024 * 4);
// 绑定并侦听某个端口
ChannelFuture future = bootstrap.bind(Integer.valueOf(StartOnLoad.NETTY_PORT)).sync();
Logger.getLogger(NettyServer.class).debug("server start ......");
MetricsUtils.start();
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
}