学习一个框架的源码思路我们通常由以下几点入手:
1:这个框架到底用来干嘛的
2:会使用这个框架
3:框架的整体架构设计思想
话很少,但这几点很重要,这样才能理解到设计者的思想。
在我看来学习框架源码最重要目的: 自己能学到怎么写出更好的代码!对源代码中代码的实现的细节和算法自己要尝试 并且把设计思维抽上来!
netty用来干什么的和使用怎么使用netty网上有很多,这里我们从Netty的整个架构设计开始
框架的整体架构设计思想:
贴张官网的门匾大标
翻译成普通话来说:
第一段就是:我是一个监听IO事件并异步化处理的框架
第二段是:Nio太TM难用的 我帮你们优化下 底层的NIO我帮你们封装掉 你们只需要关心业务就行(给NIO擦屁股 -。-)。
我需要关心的是CORE的核心代码实现
监听事件->api交换->使用buff高效处理数据的内存操作
1:事件模型设计->Reactor多线程版
我喜欢这图 思路很清晰(百度图片上找的)
netty的整个事件模型架构流程如上图
其采用的基于Nio的Reactor多线程版设计模式
解析上图
几个重要的概念
NioEventLoopGroup -> 多个或1个EventLoop = subReactor(Nio Reactor中封装的subReactor) =selector(Nio)
NioEventLoopGroup 在源码中分为ParentGrop与ChlidGrop(Nio 中的Boss与Worker)
select() ->指的是调用操作系统的epoll方法 epoll会阻塞当前线程直到有IO事件到来(NIO有个空转BUG)
pipelie -> 简单点看就是个虚拟的双向链表 里面按顺序封装了执行的handler 有入有出(Netty具体设计很巧妙)
handler -> ChlidEventLoop 是上一级的小包工头 handler就是真正的打工马仔(--.)
那么我们就回到开头
事件驱动指定是什么-> selector注册通道 调用epoll 监听事件
异步 -> 在我的理解中异步是对于channel而言的(Nio也一样) 而不是针对对Pipline中的handelr
这里用大白话说:
你去馆子里吃饭
操作系统是厨子 selector是传单员 channel就是把菜给你的服务员 handler就是你吃饭嘴
selector 看到你了(TCP连接)-> 问你想吃点什么并接单(接受管道连接)->写成菜单告诉厨子做菜(注册感兴趣事件,并调用epoll)->厨子做好了(监听) -> selector叫服务员过来(获得channel并封数据) -> 端过去就回来端下个(把数据流转入pipelie)
到这里Netty的事件模型架构模子就出来了
2:Netty组件架构
netty提供了启动专配类 bootstarp 方便地配置和启动 Netty 应用程序,Netty的入口,象脚手架一样组装了各个组件
源码开始就从bootstarp开始