zoukankan      html  css  js  c++  java
  • java高并发实战Netty+协程(Fiber)|系列1(续)|事件驱动模式和零拷贝

    上次讲到事件驱动模式,今天我们来好好分析下netty的事件模式的几个类型。

    先从NIO讲起,

    JAVA NIO方面Selector给Reactor模式提供了基础,Netty结合Selector和Reactor模式设计了高效的线程模型。

    这里有个题外话,reactor英文的含义是什么?我们可以稍微了解下:

    [ri'æktər][ri'æktə(r)]
    • n.核反应堆
    • 网络反应器;电抗器;反应者

    中文翻译是反应者,在我们这个语境,翻译成反应者或响应者,都是正解。就把它想象成KFC的前台服务员好,她就是一个响应者,也叫reactor.

    现在我们来看下Reactor模式图:

     如上图所示,所谓的reactor模式,就是我们上篇文章所说的,KFC前后服务员加后台服务员的模式。

    前台服务员(同时代表上图的demultiplexer和dispatcher)只负责接待客户的点汉堡的请求和订单分派,做汉堡的活让后台台服务员(代表上图的handler)去做。

    做好后,后台再通知前台,由前台转交给客户。

    这个很好理解。

    好,那我们现在来看看Java NIO的reactor的几个模式:单线程模式,多线程模式,主从模式。

    先看单线程模式:

     如上图所示,所谓单线程模式,只有一个线程(acceptor)去处理客户的请求,然后,这个线程还要做read,send等工作,相当于是个多面手。

    就好像KFC前台后台都只有一个服务员。

    这个模式,如果客户只有一个的话,是可以处理。但如果,是用餐高峰期,一下子来了十个客户,那就不好处理了。

     怎么办?

    很自然,我们可以增加后台服务员,并且因为后台的工作比较多,后台服务员可以多个。这就是多线程模式。

    再看多线程模式图:

     如上图所示,用线程池(多个服务员)去处理read,decode,compute,encode任务。

    就好像,前台一个服务员只负责下订单,然后把订单信息分派给多个后台服务员,同时服务多个客户,速度和效率也明显好很多,客户也不用等待太久。

     那如果,这个时间来了几十个客户,如果只有一个前台服务员,这时,也处理不过来,怎么办?

    很自然,增加前台服务员的数量。当然我们也不需要增加太多(毕竟有人力成本),现在我们只增加一位好了。

    两位服务员,一主一从,我们就叫主从模式。

    我们来看主从模式图:

    如上图,将Reactor分成两部分,mainReactor负责监听server socket,accept新连接;并将建立的socket分派给subReactor。subReactor负责多路分离已连接的socket,读写网络数据,对业务处理功能,其扔给worker线程池完成。通常,subReactor个数上可与CPU个数等同。

    还是用KFC的例子来说明,其中mainReactor是服务员小黄,她只负责下订单。subReactor就是服务员小张,他呢,只服务根据订单信息分派给后台服务员,并负责把汉堡和饮料放在托盘递给客户。

    以上就是reactor模式说明,希望你已经明白了!

    说完了Reactor的三种模型,那么Netty是哪一种呢?其实Netty的线程模型是Reactor模型的变种,那就是去掉线程池的第三种形式的变种,这也是Netty NIO的默认模式。Netty中Reactor模式的参与者主要有下面一些组件:

        Selector
        EventLoopGroup/EventLoop
        ChannelPipeline

    Selector即为NIO中提供的SelectableChannel多路复用器,充当着demultiplexer的角色,就像专门下订单的前台服务员。
    ChannelPipeline负责安排Handler的顺序及其执行。因为后台工作多且杂,需要一个后台管理员负责管理和编排后台服务员的工作。这个后台管理员就是ChannelPipeline。

    EventLoop的目的是为Channel处理IO操作,一个EventLoop可以为多个Channel服务。EventLoop就是后台服务员,一个后台服务员可以同时做几份汉堡。

    EventLoopGroup会包含多个EventLoop。EventLoopGroup就是后台服务员的班组,几个后台服务员一个班组,一个班组固定处理一个固定 的后台工作。

    明天继续。

    s

    本人精通java高并发,DDD,微服务等技术实践,专注java,rust技术栈。 本人姓名郭莹城,坐标深圳,前IBM架构师、咨询师、敏捷开发技术教练,前IBM区块链研究小组成员、十多年架构设计工作经验,《区块链核心技术与应用》作者之一, 现聚焦于:区块链创投与交易所资源对接和技术咨询。 工作微信&QQ:360369487,区块链创投与交易所资源对接,加我注明:博客园+对接,技术咨询和顾问,加我注明:博客园+顾问。想学习golang和rust的同学,也可以加我微信,备注:博客园+golang或博客园+rust,谢谢!
  • 相关阅读:
    轻重搭配
    EF的优缺点
    使用bootstrap-select有时显示“Nothing selected”
    IIS发布 HTTP 错误 500.21
    js添加的元素无法触发click事件
    sql server查看表是否死锁
    sql server把一个库表的某个字段更新到另一张表的相同字段
    SQLSERVER排查CPU占用高的情况
    SQL server中如何按照某一字段中的分割符将记录拆成多条
    LINQ to Entities does not recognize the method 'System.DateTime AddDays(Double)' method, and this method cannot be translated into a store expression.
  • 原文地址:https://www.cnblogs.com/gyc567/p/11049672.html
Copyright © 2011-2022 走看看