引导

批注 2020-07-09 112728

Bootstrap

名称描述
Bootstrap group(EventLoopGroup)设置用于处理Channel所有事件的EventLoopGroup
Bootstrap channel(Class<? extends C>), Bootstrap channelFactory( ChannelFactory<? extends C>)channel()方法指定了Channel的实现类。如果该实现类没提供默认的构造函数,可以通过调用channelFactory()方法来指定一个工厂类,它将会被bind()方法调用
Bootstrap localAddress( SocketAddress)指定Channel应该绑定到的本地地址。如果没有指定,则将由操作系统创建一个随机的地址。或者,也可以通过bind()或者connect()方法指定localAddress
Bootstrap option(ChannelOption<> option,T value)设置ChannelOption,其将被应用到每个新创建的ChannelChannelConfig。这些选项将会通过bind()或者connect()方法设置到Channel,不管哪个先被调用。这个方法在Channel已经被创建后再调用将不会有任何的效果。支持的ChannelOption取决于使用的Channel类型。
Bootstrap attr(Attribute<> key, T value)指定新创建的Channel的属性值。这些属性值是通过bind()或者connect()方法设置到Channel的,具体取决于谁最先被调用。这个方法在Channel被创建后将不会有任何的效果。
Bootstrap handler(ChannelHandler)设置将被添加到ChannelPipeline以接收事件通知的ChannelHandler
Bootstrap clone()创建一个当前Bootstrap的克隆,其具有和原始的Bootstrap相同的设置信息
Bootstrap remoteAddress(SocketAddress)设置远程地址。或者,也可以通过connect()方法来指定它
ChannelFuture connect()连接到远程节点并返回一个ChannelFuture,其将会在连接操作完成后接收到通知
ChannelFuture bind()绑定Channel并返回一个ChannelFuture,其将会在绑定操作完成后接收到通知,在那之后必须调用Channel. connect()方法来建立连接
String host = "127.0.0.1";int port = 1234;EventLoopGroup workerGroup = new NioEventLoopGroup();try {    Bootstrap b = new Bootstrap();    // 指定线程工作池    b.group(workerGroup);    // 指定实例化channel的方式    b.channel(NioSocketChannel.class);    // 连接参数    b.option(ChannelOption.SO_KEEPALIVE, true);    b.handler(new ChannelInitializer<SocketChannel>() {        @Override        public void initChannel(SocketChannel ch) throws Exception {            ch.pipeline().addLast(new TimeClientHandler());        }    });    // Start the client.    ChannelFuture f = b.connect(host, port).sync(); // (5)    // Wait until the connection is closed.    f.channel().closeFuture().sync();} catch (InterruptedException e) {    e.printStackTrace();} finally {    workerGroup.shutdownGracefully();}

ServerBootStrap

名称描述
group设置ServerBootstrap要用的EventLoopGroup。这个EventLoopGroup将用于ServerChannel和被接受的子Channel的I/O处理
channel设置将要被实例化的ServerChannel
channelFactory如果不能通过默认的构造函数创建Channel,那么可以提供一个Channel- Factory
localAddress指定ServerChannel应该绑定到的本地地址。如果没有指定,则将由操作系统使用一个随机地址。或者,可以通过bind()方法来指定该localAddress
option指定要应用到新创建的ServerChannelChannelConfigChannel- Option。这些选项将会通过bind()方法设置到Channel。在bind()方法被调用之后,设置或者改变ChannelOption都不会有任何的效果。所支持的ChannelOption取决于所使用的Channel类型。参见正在使用的ChannelConfig的API文档
childOption指定当子Channel被接受时,应用到子ChannelChannelConfigChannelOption。所支持的ChannelOption取决于所使用的Channel的类型。参见正在使用的ChannelConfig的API文档
attr指定ServerChannel上的属性,属性将会通过bind()方法设置给Channel。在调用bind()方法之后改变它们将不会有任何的效果
childAttr将属性设置给已经被接受的子Channel。接下来的调用将不会有任何的效果
handler设置被添加到ServerChannelChannelPipeline中的ChannelHandler。更加常用的方法参见childHandler()
childHandler设置将被添加到已被接受的子ChannelChannelPipeline中的Channel- Handlerhandler()方法和childHandler()方法之间的区别是:前者所添加的ChannelHandler由接受子ChannelServerChannel处理,而childHandler()方法所添加的ChannelHandler将由已被接受的子Channel处理,其代表一个绑定到远程节点的套接字
clone克隆一个设置和原始的ServerBootstrap相同的ServerBootstrap
bind绑定ServerChannel并且返回一个ChannelFuture,其将会在绑定操作完成后收到通知(带着成功或者失败的结果)

Netty 通过指定 EventLoopGroup 来决定使用哪一种 Reactor 模型

// 单线程模式:EventLoopGroup eventGroup new NioEventLoopGroup(1);// 非主从多线程:EventLoopGroup eventGroup new NioEventLoopGroup();// 主从多线程:EventLoopGroup bossGroup new NioEventLoopGroup();EventLoopGroup workerGroup new NioEventLoopGroup()
// 接收到来的连接EventLoopGroup bossGroup = new NioEventLoopGroup();// 处理已建立连接的流量EventLoopGroup workerGroup = new NioEventLoopGroup();try {    // 复制启动服务器    ServerBootstrap b = new ServerBootstrap();    b.group(bossGroup, workerGroup)            // 使用 NioServerSocketChannel 将到来的连接实例化为Channel            .channel(NioServerSocketChannel.class)            // 指定处理器来处理 channel 与 channel 的事件            .childHandler(new ChannelInitializer<SocketChannel>() {                @Override                public void initChannel(SocketChannel ch) throws Exception {                    ch.pipeline().addLast(new DiscardServerHandler());                }            })            // 指定一些参数(针对到来的连接)            .option(ChannelOption.SO_BACKLOG, 128)            // 指定一些参数(针对channel)            .childOption(ChannelOption.SO_KEEPALIVE, true);    // Bind and start to accept incoming connections.    ChannelFuture f = b.bind(port).sync();    // Wait until the server socket is closed.    // In this example, this does not happen, but you can do that to gracefully    // shut down your server.    f.channel().closeFuture().sync();} finally {    workerGroup.shutdownGracefully();    bossGroup.shutdownGracefully();}

尽可能重用 EventLoop , 减少先创创建所带来的的开销

ChannelOption

bootstrap.option(ChannelOption.SO_KEEPALIVE,true)  .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000);

ChannelOption.SO_BACKLOG对应的是tcp/ip协议listen函数中的backlog参数,函数listen(int socketfd,int backlog)用来初始化服务端可连接队列,服务端处理客户端连接请求是顺序处理的,所以同一时间只能处理一个客户端连接,多个客户端来的时候,服务端将不能处理的客户端连接请求放在队列中等待处理,backlog参数指定了队列的大小

Channeloption.SO_KEEPALIVE参数对应于套接字选项中的SO_KEEPALIVE,该参数用于设置TCP连接,当设置该选项以后,连接会测试链接的状态,这个选项用于可能长时间没有数据交流的连接。当设置该选项以后,如果在两小时内没有数据的通信时,TCP会自动发送一个活动探测数据报文

关闭

Future<?> future = group.shutdownGracefully();  ← --  shutdownGracefully()方法将释放所有的资源,并且关闭所有的当前正在使用中的Channel// block until the group has shutdownfuture.syncUninterruptibly();