我们晓得了Nginx是做什么的以及它为什么这般高效率,以致于Auneau拿它来做阻抗平衡换句话说web server。
但是如果你罢了介绍了采用和晓得了基本原理就认为已经掌控了它,那根本无法说你幼稚了,基本原理和采用专业技能看一看大家都晓得了,没必要性掏出去和自己拽,凡是你和自己说Nginx的epoll我确切,Master-Worker是怎样工作的,最高级球手可能真的你真牛,你真吓人,不过遇到剑客了,你那最多罢了熟识了那个模块罢了,你并没有数不清的高速成长,而剑客透过对Nginx的深入细致介绍,他能辨认出其中的秘笈,那个秘笈能协助他Monestier其他模块,进而用最短的时间掌控更多的控制技术,在网络应用领域立足于后来居上。
所以剑客是怎样透过对Nginx的自学使自己达到更高的修为呢?
程序语言
别笑,专业委员会了程序语言,你就能骄傲的讲出古龙老先生在《孔明神雕侠侣》里秘传心法的算数:他强由他强,春风拂小丘;他横由他横,由丽大川。他自狠来他自恶,我自几口精气足。懂得人都懂,不懂的人自悟。
宽恕我说所以多,请开始自问自答Reactor商业模式。
1. Reactor商业模式如是说
后面有写Reactor商业模式的该文,那首诗主要是普及化下基本概念,此次是重点项目如是说。
Reactor 商业模式,是指透过一个或数个输出同时传达给服务项目CPU的服务项目允诺的该事件驱动处理商业模式。服务项目端程序处理传入多路允诺,并将它们同步分派给允诺对应的处理线程,Reactor 商业模式也叫 Dispatcher 商业模式。
即I/O多路复用统一监听该事件,收到该事件后分发(Dispatch 给某进程),是编写高性能网络服务项目器的必备控制技术之一。
Reactor 商业模式中有 2 个关键组成:
Reactor:Reactor在一个单独的线程中运行,负责监听和分发该事件,分发给适当的处理程序来对 IO 该事件做出反应。它就像公司的电话接线员,它接听来自客户的电话并将线路转移到适当的联系人;Handlers:处理程序执行 I/O 该事件要完成的实际该事件,类似于客户想要与之交谈的公司中的实际官员。Reactor 透过调度适当的处理程序来响应 I/O 该事件,处理程序执行非阻塞操作。根据 Reactor 的数量和处理资源池线程的数量不同,有 3 种典型的实现:
单 Reactor 单线程单 Reactor 多线程主从 Reactor 多线程下面详细如是说这 3 种实现方式。
2. 单 Reactor 单线程
其中,Select是后面 I/O 复用模型如是说的标准网络编程API,能实现应用程序透过一个阻塞对象监听多路连接允诺,其他方案示意图类似。
方案说明:
Reactor 对象透过 Select 监控客户端允诺该事件,收到该事件后透过 Dispatch 进行分发;如果是建立连接允诺该事件,则由 Acceptor 透过 Accept 处理连接允诺,然后创建一个 Handler 对象处理连接完成后的后续业务处理;如果不是建立连接该事件,则 Reactor 会分发调用连接对应的 Handler 来响应;Handler 会完成 Read→业务处理→Send 的完整业务流程。优点:模型简单,没有多线程、进程通信、竞争的问题,全部都在一个线程中完成(Reactor单线程)。缺点:性能问题,只有一个线程,无法完全发挥多核 CPU 的性能。Handler 在处理某个连接上的业务时,整个进程无法处理其他连接该事件,很容易导致性能瓶颈。3. 单 Reactor 多线程
方案说明:
Reactor 对象透过 Select 监控客户端允诺该事件,收到该事件后透过 Dispatch 进行分发;如果是建立连接允诺该事件,则由 Acceptor 透过 Accept 处理连接允诺,然后创建一个 Handler 对象处理连接完成后续的各种该事件;如果不是建立连接该事件,则 Reactor 会分发调用连接对应的 Handler 来响应;Handler 只负责响应该事件,不做具体业务处理,透过 Read 读取数据后,会分发给后面的 Worker 线程池进行业务处理;Worker 线程池会分配独立的线程完成真正的业务处理,最后将响应结果发给 Handler 进行处理;Handler 收到响应结果后透过 Send 将响应结果返回给 Client。优点:能充分利用多核 CPU 的处理能力。缺点:多线程数据共享和访问比较复杂;Reactor 承担所有该事件的监听和响应,在单线程中运行,高并发场景下容易成为性能瓶颈。相关视频推荐
需要C/C++ Linux服务项目器架构师自学资料加qun812855908C/C++,Linux,golang控制技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享
4. 主从 Reactor 多线程
针对单 Reactor 多线程模型中,Reactor 在单线程中运行,高并发场景下容易成为性能瓶颈,能让 Reactor 在多线程中运行。
方案说明:
Reactor 主线程 MainReactor 对象透过 Select 监控建立连接该事件,收到该事件后透过 Acceptor 接收,处理建立连接该事件;Acceptor 处理建立连接该事件后,MainReactor 将连接分配 Reactor 子线程给 SubReactor 进行处理;SubReactor 将连接加入连接队列进行监听,并创建一个 Handler 用于处理各种连接该事件;当有新的该事件发生时,SubReactor 会调用连接对应的 Handler 进行响应;Handler 透过 Read 读取数据后,会分发给后面的 Worker 线程池进行业务处理;Worker 线程池会分配独立的线程完成真正的业务处理,最后将响应结果发给 Handler 进行处理;Handler 收到响应结果后透过 Send 将响应结果返回给 Client。优点:父线程与子线程的数据交互简单职责明确,父线程只需要接收新连接,子线程完成后续的业务处理。父线程与子线程的数据交互简单,Reactor 主线程只需要把新连接传给子线程,子线程无需返回数据。缺点:代码写起来太复杂了:即编程复杂度较高。5. Reactor小结
3种商业模式能用个比喻来理解:(餐厅常常雇佣接待员负责迎接顾客,当顾客入坐后,侍应生专门为这张桌子服务项目)
单 Reactor 单线程,接待员和侍应生是同一个人,全程为顾客服务项目;单 Reactor 多线程,1 个接待员,数个侍应生,接待员只负责接待;主从 Reactor 多线程,数个接待员,数个侍应生。Reactor 商业模式具有如下的优点:
响应快,不必为单个同步时间所阻塞,虽然 Reactor 本身依然是同步的;编程相对简单,能最大程度的避免复杂的多线程及同步问题,并且避免了多线程/进程的切换开销;可扩展性,能方便的透过增加 Reactor 实例个数来充分利用 CPU 资源;可复用性,Reactor 模型本身与具体该事件处理逻辑无关,具有很高的复用性。6. Nginx利用的就是主从Reactor商业模式
但它和主从reactor商业模式又有一定的区别,区别主要就是那个master进程,那个master进程不同于一般的主从式reactor(一般的主从式reactor设计会是主reactor负责将连接accept下来,然后再将连接fd挂载到子reactor中),那个master进程的主要任务就是监听信号的,也就是对nginx的一些命令做处理,然后再将这些处理透过sockerpair()或者信号等方式通知给worker进程,master进程同时监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。同时,那个master进程负责listen那个整个服务项目器的监听fd,然后worker进程透过竞争accept_mutex互斥锁来将连接从全连接队列里取出来,然后进行后续的该事件循环处理。
也就是说除了Master与主从Reactor中的主线程Reactor不同以外,Worker的处理流程和子线程Reactor的处理流程几乎一摸一样,用陈硕老师的话来说就是reactors in process。
7. 小结
晓得了Reactor商业模式之后再回头想想看一看哪些你介绍的服务项目或者中间件采用了此商业模式,要专业委员会Monestier才能更胜一筹,进而成为剑客。那个商业模式还有一个最精妙的地方在于把复杂的问题透过”中间层”的方式简单化。计算机界不是有句老话:“凡是服务项目不能透过现有常规控制技术手段解决的,就加一个中间层来解决”。此话真的一语点醒梦中人,Reactor主从商业模式把频繁的accept过程,其他fd的并发IO处理过程以及业务处理逻辑部分分层,透过加层的方式让整个商业模式快速而高效率的运行起来,这就是智慧,人类的智慧。