netty 系列二:架构设计

目录

 

前置知识:

Java 4种IO模型

网络模型和TCP协议

Reactor线程模型

Netty模型

netty核心组件

channel

EventLoop、EventLoopGroup

ChannelHandler

ChannelPipeline

Bootstrap


前置知识:

Java 4种IO模型

网络模型和TCP协议

Reactor线程模型

Reactor线程模型不是Java专属,也不是Netty专属,它其实是一种并发编程模型,是一种思想,具有指导意义。比如,Netty就是结合了NIO的特点,应用了Reactor线程模型所实现的。 Reactor模型中定义的三种角色:

Reactor:负责监听和分配事件,将I/O事件分派给对应的Handler。新的事件包含连接建立就绪、 读就绪、写就绪等。

Acceptor:处理客户端新连接,并分派请求到处理器链中。

Handler:将自身与事件绑定,执行非阻塞读/写任务,完成channel的读入,完成处理业务逻辑 后,负责将结果写出channel。

常见的Reactor线程模型有三种,如下:

Reactor单线程模型

Reactor多线程模型

主从Reactor多线程模型

Reactor单线程模型:

Reactor充当多路复用器角色,监听多路连接的请求,由单线程完成

Reactor收到客户端发来的请求时,如果是新建连接通过Acceptor完成,其他的请求由Handler完成。

Handler完成业务逻辑的处理,基本的流程是:Read --> 业务处理 --> Send 。

优点

结构简单,由单线程完成,没有多线程、进程通信等问题。

适合用在一些业务逻辑比较简单、对于性能要求不高的应用场景。

缺点

单线程操作,不能充分发挥多核CPU的性能。 当Reactor线程负载过重之后,处理速度将变慢,这会导致大量客户端连接超时

稳定性差,一旦某个业务处理读写或者业务逻辑慢,拖慢整个通信系统

Reactor多线程模型

对单线程模型的改进,业务处理由单独的线程处理

好处是增加了业务处理的吞吐量,但是Reactor还是要处理读写请求,当qps过大时,还是会问题。再进一步改进,就是主从Reactor多线程模型。

主从Reactor多线程模型

主的Reactor新建连接交给Acceptor处理,连接建立后,把channel注册到SubReactor。由SubReactor处理channel的读写请求。

Netty模型

Netty的模型,就是主从Reactor多线程模型

Group就是线程池,BoosGroup处理连接请求,交给Acceptor。Acceptor新建channel后,注册到workGroup。

channel读写事件,由workGroup线程池处理。

netty核心组件

channel

Channel可以理解为是socket连接,在客户端与服务端连接的时候就会建立一个Channel,它负责基本

的IO操作,比如:bind()、connect(),read(),write() 等。 主要作用:

1. 通过Channel可获得当前网络连接的通道状态。
2. 通过Channel可获得网络连接的配置参数(缓冲区大小等)。
3. Channel提供异步的网络I/O操作,比如连接的建立、数据的读写、端口的绑定等。

不同协议、不同的阻塞类型的连接都有不同的 Channel 类型与之对应,常用的 Channel 类型:

NioSocketChannel,NIO的客户端 TCP Socket 连接。 NioServerSocketChannel,NIO的服务器端 TCP Socket 连接。
NioDatagramChannel, UDP 连接。
NioSctpChannel,客户端 Sctp 连接。
NioSctpServerChannel,Sctp 服务器端连接,这些通道涵盖了 UDP 和 TCP 网络 IO 以及文件 IO。

EventLoop、EventLoopGroup

有了 Channel 连接服务,连接之间可以消息流动。如果服务器发出的消息称作“出站”消息,服务器接受

的消息称作“入站”消息。那么消息的“出站”/“入站”就会产生事件(Event)。 例如:连接已激活;数据读取;用户事件;异常事件;打开链接;关闭链接等等。

有了事件,就需要一个机制去监控和协调事件,这个机制(组件)就是EventLoop。
在 Netty 中每个 Channel 都会被分配到一个 EventLoop。一个 EventLoop 可以服务于多个 Channel。

每个 EventLoop 会占用一个 Thread,同时这个 Thread 会处理 EventLoop 上面发生的所有 IO 操作和 事件。

ChannelHandler

ChannelHandler对使用者而言,可以说是最重要的组件了,因为对于数据的入站和出站的业务逻辑的

编写都是在ChannelHandler中完成的。 在前面的例子中,MyChannelHandler就是实现了channelRead方法,获取到客户端传来的数据。 对于数据的出站和入站,有着不同的ChannelHandler类型与之对应:

ChannelInboundHandler 入站事件处理器

ChannelOutBoundHandler 出站事件处理器

ChannelInboundHandlerAdapter 与 SimpleChannelInboundHandler的区别:

在服务端编写ChannelHandler时继承的是ChannelInboundHandlerAdapter 在客户端编写ChannelHandler时继承的是SimpleChannelInboundHandler 两者的区别在于,前者不会释放消息数据的引用,而后者会释放消息数据的引用。

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        boolean release = true;
        try {
            if (acceptInboundMessage(msg)) {
                @SuppressWarnings("unchecked")
                I imsg = (I) msg;
                channelRead0(ctx, imsg);
            } else {
                release = false;
                ctx.fireChannelRead(msg);
            }
        } finally {
            if (autoRelease && release) {
                ReferenceCountUtil.release(msg);
            }
        }
    }

ChannelPipeline

在Channel的数据传递过程中,对应着有很多的业务逻辑需要处理,比如:编码解码处理、读写操作 等,那么对于每种业务逻辑实现都需要有个ChannelHandler完成,也就意味着,一个Channel对应着 多个ChannelHandler,多个ChannelHandler如何去管理它们,它们的执行顺序又该是怎么样的,这就 需要ChannelPipeline进行管理了。

一个Channel包含了一个ChannelPipeline,而ChannelPipeline中维护了一个ChannelHandler的列 表。

ChannelHandler与Channel和ChannelPipeline之间的映射关系,由ChannelHandlerContext进行维 护。

ChannelHandler按照加入的顺序会组成一个双向链表,入站事件从链表的head往后传递到最后一个 ChannelHandler,出站事件从链表的tail向前传递,直到最后一个ChannelHandler,两种类型的 ChannelHandler相互不会影响。

Bootstrap

Bootstrap是引导的意思,它的作用是配置整个Netty程序,将各个组件都串起来,最后绑定端口、启动

Netty服务。 Netty中提供了2种类型的引导类,一种用于客户端(Bootstrap),而另一种(ServerBootstrap)用于服务

器。 它们的区别在于:

ServerBootstrap 将绑定到一个端口,因为服务器必须要监听连接,而 Bootstrap 则是由想要连接 到远程节点的客户端应用程序所使用的。

引导一个客户端只需要一个EventLoopGroup,但是一个ServerBootstrap则需要两个。

              因为服务器需要两组不同的 Channel
              第一组将只包含一个 ServerChannel,代表服务器自身的已绑定到某个本地端口的正在监听 的套接字。
              第二组将包含所有已创建的用来处理传入客户端连接。

与ServerChannel相关联的EventLoopGroup 将分配一个负责为传入连接请求创建 Channel 的 EventLoop。一旦连接被接受,第二个 EventLoopGroup 就会给它的 Channel 分配一个 EventLoop。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值