【闪电侠学netty】第4章 服务端启动流程

【Netty】读书笔记 - 跟闪电侠学

1. 内容概要

1 服务端启动最小化代码

启动服务器步骤

  • Step1:线程模型,服务器引导类ServerBootstrap 
  • Step2:IO 模型
  • Step3:IO 处理逻辑
  • Step4:绑定本地端口,启动服务
public class NettyServer {

    private static final int BEGIN_PORT = 8000;

    public static void main(String[] args) {
        //boosGroup :监听端口,接收新连接的线程组
        //workerGroup :处理每一个连接的数据读写的线程组
        NioEventLoopGroup boosGroup = new NioEventLoopGroup();
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();

        final ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap
                .group(boosGroup, workerGroup)//Step1:线程模型
                .channel(NioServerSocketChannel.class)//Step2:IO模型
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    protected void initChannel(NioSocketChannel ch) {
                        //Step3:连接读写处理逻辑
                        System.out.println(ch.attr(clientKey).get());
                    }
                });

        //Step4:绑定本地端口,启动服务
        serverBootstrap.bind(8000);
    }
}


2 自动绑定递增端口

        绑定监听器,监听端口是否绑定成功,不成功继续绑定下一个端口port+1

public class NettyServer {

    private static final int BEGIN_PORT = 8000;

    public static void main(String[] args) {
        NioEventLoopGroup boosGroup = new NioEventLoopGroup();
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();

        final ServerBootstrap serverBootstrap = new ServerBootstrap();
        final AttributeKey<Object> clientKey = AttributeKey.newInstance("clientKey");
        serverBootstrap
                .group(boosGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .attr(AttributeKey.newInstance("serverName"), "nettyServer")
                .childAttr(clientKey, "clientValue")
                .option(ChannelOption.SO_BACKLOG, 1024)
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childOption(ChannelOption.TCP_NODELAY, true)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    protected void initChannel(NioSocketChannel ch) {
                        System.out.println(ch.attr(clientKey).get());
                    }
                });


        bind(serverBootstrap, BEGIN_PORT);
    }

    private static void bind(final ServerBootstrap serverBootstrap, final int port) {
        serverBootstrap.bind(port).addListener(future -> {
            if (future.isSuccess()) {
                System.out.println("端口[" + port + "]绑定成功!");
            } else {
                System.err.println("端口[" + port + "]绑定失败!");
                bind(serverBootstrap, port + 1);
            }
        });
    }
}


3 服务端启动的其他方法

如 serverBootstrap.childHandler()

方法名是否常用描述
handler()用于指定在服务器启动过程中的一些逻辑
childHandler()用于指定处理新连接数据的读写处理逻辑
attr()给服务端Channel指定自定义属性,通过channel.attr()取出属性
childattr()给每一个连接指定自定义属性通过channel.attr()取出属性
option()

serverBootstrap
        .option(ChannelOption.SO_BACKLOG, 1024)

给服务器设置一些TCP参数,最常见的是so_backlog

so_backlog:临时存放已完成三次握手的请求队列的最大长度,服务器创建新连接较慢,可以调大这个参数

childoption()

serverBootstrap
        .childOption(ChannelOption.SO_KEEPALIVE, true)//默认:false
        .childOption(ChannelOption.TCP_NODELAY, true)//默认:false

ChannelOption.SO_KEEPALIVE:是否开启TCP底层心跳机制,true:开启

ChannelOption.TCP_NODELAY:是否开启Nagle算法,true:关闭,false: 开启

通俗讲,要求高实时性,有数据马上发送就设置true:关闭

posted @ 2023-01-17 11:09  随风落木  阅读(21)  评论(0)    收藏  举报  来源