不使用netty是怎么实现网络通信的
netty是一个网络框架, 本篇会向你介绍netty的整体结构.
回忆下我们在上学时实现的"聊天室小程序", 当时是如何做的. 首先我们定义两个系统Server和Client, 然后在Server端构造一个ServerSocket, 绑定一个端口port, 通过accept()方法等待请求进来, 为了处理多个请求, 通常我们在这里获取到请求后会将具体的处理任务派给其他线程处理, 当前线程继续accept()等待下一次请求. Client这边会构造一个Socket, 绑定端口port. 这就是一个通信的小程序大概的结构, 如图所示为一次数据通信
1 服务端创建ServerSocket
2 服务端创建监听线程accept thread和工作线程池work thread pool
3 客户端创建Socket, 此时建立了连接connection
4 客户端创建工作线程work thread
5 客户端发送请求request, 服务端accept thread监听到request, 并分配给work thread pool中的某个线程
6 work thread 处理信息
7 返回信息给Client
整个通信流程大概就是这样, 看起来虽然步骤比较多, 但是好像我也可以实现! 当然netty不会这么简单(虽然还不知道哪里不简单~), 不过整体网络通信思路差不多. 下面来看下netty的通信过程.
netty通信过程
先上图
老板是不是没换碟~~
虽然netty很吊, 但是网络通信的玩法还是这样, 要通信就要先在两个端点建立连接, 为了提高吞吐就需要开启多个线程处理不同类型的消息或者行为. netty牛X的地方是这几个部分的具体实现上, 下面根据这个图大概说下netty的整体结构.
netty整体结构
netty整体分为三层: 网络通信层, 事件调度层, 服务编排层
网络通信层
网络通信层有三个主要的组件: ServerBootstrap, Bootstrap, Channel
ServerBootstrap & Bootstrap
Bootstrap就是启动, 引导的意思. ServerBootstrap和Bootstrap分别是服务端和客户端启动netty的引导类. 虽然我们在图中将其类比为ServerSocket和Socket, 但是这两个Bootstrap功能要强大的多, 一方面需要创建连接, 另一方面还要负责系统的初始化工作, 总之就是整个系统的入口.
ServerBootstrap和Bootstrap很相似, 区别:ServerBootstrap作用于服务端, Bootstrap作用于客户端, 服务端比客户端就多了需要监听请求的工作, 在netty中将监听请求的线程组(EventLoopGroup)为Boss, 处理请求的线程组为Worker(啧啧~). 而客户端只需要一个Worker线程组. 这些线程处理的数据被封装为Channel.
Channel
Channel作为"通信管道"的抽象, 贯穿整个流程. 想象一个水管, 对于水管来说, 它知道里面有水还是没有水(就绪), 知道一端有没有桶来接水(注册). 这些其实就对应Channel的不同状态, 不同状态都有对应的事件回调, 后面我们会再详细的看各种状态(因为现在我也不清楚~), 那么事件回调操作是如何执行的呢? 这就是事件调度层要做的事.
事件调度层
这一层主要就是Boss和Worker这哥俩, 它们都是线程池, 叫作EventLoopGroup, 其中的线程叫作EventLoop. 当接收到一个Channel时, EventLoopGroup会选择一个EventLoop与该Channel绑定(注册). 那么该Channel中的各种事件回调就需要这个EventLoop去执行, 那么具体的执行内容又是什么? 那就要看服务编排层.
服务编排层
服务编排层就是一条流水线, 称为ChannelPipeline(处理Channel的流水线), 每一个处理节点都是一个ChannelHandler, ChannelHandlerContext中保存了ChannelHandler需要的上下文信息.
结尾
以上就是第一节课的总结, 对netty的整体结构有了简单的了解, 后面再慢慢补充细节