8-网络架构和Netty系列-ServerBootstrap运行过程

ServerBootstrap运行过程

服务端从启动到新连接的改变过程

ServerBootstrap初始化过程

(1)EventLoopGroup:无论是服务端还是客户端,都必须指定EventLoopGroup。在上面的代码中,指定了NioEventLoopGroup,表示一个NIO的EventLoopGroup,不过服务端需要指定两个EventLoopGroup,一个是bossGroup,用于处理客户端的连接请求;另一个是workerGroup,用于处理与各个客户端连接的I/O操作。

(2)指定Channel的类型。这里是服务端,所以使用了NioServerSocketChannel。

(3)配置自定义的业务处理器Handler。

NioServerSocketChannel

public NioServerSocketChannel(ServerSocketChannel channel) {
  	//设置SelectionKey.OP_ACCEPT,也就是通知Selector我们对客户端的连接请求感兴趣
    super(null, channel, SelectionKey.OP_ACCEPT);
    config = new NioServerSocketChannelConfig(this, javaChannel().socket());
}

(1)调用NioServerSocketChannel.newSocket(DEFAULT_SELECTOR_PROVIDER)方法创建一个新的Java NIO原生的ServerSocketChannel对象。

(2)实例化AbstractChannel对象并给属性赋值,具体赋值的属性如下。

● parent:设置为默认值null。

● unsafe:通过调用newUnsafe()方法,实例化一个Unsafe对象,其类型是AbstractNioMessageChannel.AbstractNioUnsafe内部类。

● pipeline:赋值的是DefaultChannelPipeline的实例。

(3)实例化AbstractNioChannel对象并给属性赋值,具体赋值的属性如下。

● ch:被赋值为Java NIO原生的ServerSocketChannel对象,通过调用NioServerSocketChannel的newSocket()方法获取。● readInterestOp:被赋值为默认值SelectionKey.OP_ACCEPT。

● Ch:被设置为非阻塞,也就是调用ch.configureBlocking(false)方法。

(4)给NioServerSocketChannel对象的config属性赋值为new NioServerSocketChannelConfig(this,javaChannel().socket())。

EventLoop启动完整过程

在这里插入图片描述

ServerBootstrapAcceptor

ServerBootstrap#init()

ServerBootstrap#init(){
        p.addLast(new ChannelInitializer<Channel>() {
            @Override
            public void initChannel(Channel ch) throws Exception {
                ChannelPipeline pipeline = ch.pipeline();
                ChannelHandler handler = handler();
                if (handler != null) {
                    pipeline.addLast(handler);
                }
                //读取客户端连接
                pipeline.addLast(new ServerBootstrapAcceptor(
                        currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
            }
        });
}

private static class ServerBootstrapAcceptor extends ChannelInboundHandlerAdapter {
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            final Channel child = (Channel) msg;

            child.pipeline().addLast(childHandler);

            for (Entry<ChannelOption<?>, Object> e: childOptions) {
......

            try {
            //childGroup的register()方法就是将workerGroup中的某个EventLoop和NioSocketChannel进行关联
                childGroup.register(child).addListener(new ChannelFutureListener() {
                    ......
                });
            } catch (Throwable t) {
                forceClose(child, t);
            }
        }
}

bossGroup与workerGroup

bossGroup只用于服务端的accept,也就是用于处理客户端新连接接入的请求。我们可以把Netty比作一个餐馆,bossGroup就像一个大堂经理,当客户来到餐馆吃饭时,大堂经理就会引导顾客就座,为顾客端茶送水等。而workerGroup就是实际干活的厨师,它们负责客户端连接通道的I/O操作:当大堂经理接待顾客后,顾客可以稍做休息,而此时后厨里的厨师们(workerGroup)就开始忙碌地准备饭菜了

在这里插入图片描述

Pipeline设计原理*

在这里插入图片描述

在初始化Bootstrap时通过handler()方法设置的ChannelInitializer实例,因此这里就将ChannelInitializer插到了Pipeline的末端

自定义ChannelHandler的添加过程

在这里插入图片描述

Pipeline的事件传播机制

Inbound事件和Outbound事件的流向是不一样的,

Inbound事件的流向是从下至上的,是通过调用相应的ChannelHandlerContext.fireIN_EVT()方法来传递的.

Outbound恰好相反,是从上到下,是通过调用ChannelHandlerContext.OUT_EVT()方法来传递的

例如:ChannelHandlerContext的fireChannelRegistered()调用会发送一个ChannelRegistered的Inbound给下一个ChannelHandlerContext,而ChannelHandlerContext的bind()方法调用时会发送一个bind的Outbound事件给下一个ChannelHandlerContext。

Outbound事件传播方式

在这里插入图片描述

Inbound事件传播方式

在这里插入图片描述

Inbound类似于事件回调(响应请求的事件),而Outbound类似于主动触发(发起请求的事件)

ChannelHandlerContext*

在ServerBootstrapAcceptor章节出现

每个ChannelHandler被添加到ChannelPipeline后,都会创建一个ChannelHandlerContext,并与ChannelHandler关联绑定。ChannelHandlerContext允许ChannelHandler与其他的ChannelHandler进行交互。ChannelHandlerContext不会改变添加到其中的ChannelHandler,因此它是安全的。ChannelHandlerContext、ChannelHandler和ChannelPipeline的关系如下图所示

在这里插入图片描述

Channel的生命周期

一个Channel正常的生命周期如下图所示。随着状态发生变化产生相应的事件。这些事件被转发到ChannelPipeline中的ChannelHandler来触发相应的操作。

在这里插入图片描述

在这里插入图片描述

异步结果Future&异步执行Promise

通过 Future 和 ChannelFutures,他们可以注册一个监听,当操作执行成功或失败时监听会自动触发注册的监听事件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xianghan收藏册

极简精品作,一分也是一份鼓励哦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值