- Netty是什么? 
  - Netty是Jboss提供的一个Java 开源框架,主要针对TCP协议的高并发场景
- Netty本质是对Java NIO做了封装的网络通信框架,主要作用是Java NIO基本接口的封装,提供了网络通信中线程同步,编解码,粘包拆包,闪断重连等问题的封装,方便我们利用API方便的开发;
- 提供了完整的ssl/tsl支持;
- 另外Netty解决了NIO中的selector空轮训的Bug;
- Netty 线程模型为多reactor多线程模型-1+n+m,但是Netty提供了灵活配置,也可以实现单reactor单线程,单reactor多线程模型;
 
- Netty的启动流程 
  - 先上代码
 
public class HelloServer {
    public static void main(String[] args) {
        NioEventLoopGroup bossGroup=new NioEventLoopGroup(1);
        NioEventLoopGroup workGroup=new NioEventLoopGroup();
        new ServerBootstrap()
                //1、绑定线程池组
                .group(bossGroup,workGroup) 
                //2、定义主reactor线程处理Handler
                .handler(new LoggingHandler(LogLevel.DEBUG))
                //3、选择服务器的ServerSocketChannel实现
                .channel(NioServerSocketChannel.class)
                //4、boss:负责处理连接;worker:处理读写,决定了worker(child)能执行哪些操作(handler)
                .childHandler(
                        //5、Channel代表和客户端进行数据读写的通道,Initializer初始化器,负责添加别的handler
                        new ChannelInitializer<NioSocketChannel>() {
                            @Override
                            protected void initChannel(NioSocketChannel ch) throws Exception {
                                //添加具体的handler
                                ch.pipeline().addLast(new StringDecoder()); //17、将ByteBuf转换为字符串,然后给下一个处理器
                                ch.pipeline().addLast(new ChannelInboundHandlerAdapter() { //自定义handler
                                    @Override //读事件
                                    //18、执行channelRead()方法,打印hello
                                    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                        System.out.println("WorkGroup thread name----"+Thread.currentThread().getName());
                                        System.out.println(msg);
                                        System.out.println(ctx.pipeline().names());
                                    }
                                });
                            }
                        })
                //6、绑定监听端口
                .bind(8888);
    }
}- Netty提供了启动引导类ServerBootstrap,使用Builder模式来帮助构建启动Netty服务器程序,提供了灵活的配置需求;
- 基本说明-- 
  - Netty启动过程就是加载配置项--主从reactor执行线程池组,socketchannel的Handler,监听端口;
- 然后创建serversocketchannel注册到主reactor线程上,监听新连接事件,将新的连接分发到从reactor线程的eventloop中;
- 这里Netty对serversocketchannel提供了默认的Handler实现对新连接创建socketchannel并分发给从reactor的逻辑;
- 首先通过group方法指定了主从reactor线程池组,bossGroup对应主reactor线程,负责监听端口处理连接请求,新连接请求将创建socketchannel并分发注册到workerGroup中的eventloop上,由workerGroup中的eventloop监听IO事件并调用相应的Handler来处理IO事件;
- 每一个eventloop对应一个单例线程池,对应一个selector对象,接受一个或多个channel注册,监听读写事件;
- Netty启动并初始化的核心逻辑在体现在bind()方法中,bind方法创建serversocketchannel并注册到bossGroup中的eventloop上,并为serversocketchannel提供默认用来创建新连接的Handler----ServerBootstrapAcceptor
- 总体来说,网络通信的基本过程为--- 
    - 创建serversocketchannel监听端口,处理connect事件
- 创建socketchannel监听连接,处理IO事件
- 而Netty启动则完成了第一步;
 
 
- Netty中的核心类型说明 
  - NioEventLoop
 
Netty启动首先创建了两个nioeventloopgroup对象,这两个对象字面理解就是两个nioEventLoop数组,所以核心是NioEventLoop,看一下源码--
public final class NioEventLoop extends SingleThreadEventLoop {
    private Selector selector;
    private SelectedSelectionKeySet selectedKeys;
    private final SelectorProvider provider;
    private final SelectStrategy selectStrategy;
    //注册socketchannel到selector
    public void register(final SelectableChannel ch, final int interestOps, final NioTask<?> task);
    //重新构建selector--JDK NIO中的selector的空轮训Bug解决方案
    public void rebuildSelector();
    //eventloop运行主逻辑
    protected void run();
}NioEventLoop可以说是Netty的reactor核心逻辑的实现,主要继承了抽象类SingleThreadEventLoop,单线程处理NIO事件循环通知;而SingleThreadEventLoop的继承和实现关系如下:

代码实例中只写了极少一部分体现核心逻辑的方法和实例属性,主要为了概念上说明NioEventLoop的工作机制,具体详细的实现在后续专门说明;
NioEventLoop的工作原理-
- EventLoop核心是一个线程处理事件循环;
- NioEventLoop则是运行selector方法,完成对注册在selector上的channel的网络事件监听,这也就是reactor模型的基本实现----IO多路复用和事件监听;
- 另外NioEventLoop继承了SingleThreadEventLoop,除了监听selector之外还可以监听通过父类的execute()方法提交的任务和schedule方法提交的定时任务;
- rebuildSelector()方法是NioEventLoop对JDK中的selector空轮训的Bug实现的解决方案----空轮训次数超过默认512次后重新构建一个新的selector对象; 
- register()方法用于在新连接建立后向EventLoop中的selector注册连接对应的socketchannel;
- run()方法则是一个死循环,对selector和注册的其他异步任务进行轮训,监听到事件发生时则执行对应的Handler来处理事件;
2.NioEventLoopGroup
NioEventLoopGroup 是一个线程数组,继承了MultithreadEventLoopGroup,

主要提供了对NioEventLoop 初始化的参数,用来创建NioEventLoop实例,默认创建CPU核数*2个线程(EventLoop)--

另外MultithreadEventLoop继承了EventExecutorChooser选择器的实现,选择器用来做任务分发----NioEventLoopGroup 是一个线程池,当向NioEventLoopGroup注册一个新的channel的时候具体分发给哪一个EventLoop的selector来监听该channel上的IO事件;这里对选择器的实现机制不多做解释,大概对NioEventLoopGroup的主要功能逻辑做一个说明;
3.ChannelHandler
channelHandler是事件处理器的实现,netty中通过责任链模式实现对事件的层层处理,责任链模式的主体对象是pipeline,相当于一个双向链表,分别对应出站(从服务端到客户端)和入站(从客户端向服务端)方向的事件处理,这里出站和入战是相对的,对本netty服务来说,接收外部的其他服务请求即为入站,反之主动向其他netty服务发出请求即为出站,简单理解为接收数据即为入站,发送数据即为出站;当事件发生的时候,EventLoop就会调用对应的channel的Handler来处理具体的逻辑--底层的ByteBuffer的读写,上层业务逻辑处理等等;

总结:netty通过EventLoop单线程执行selector来监听注册在其上的网络IO事件和用户在Handler中提交的异步任务,然后对不同的事件调用不同的Handler来处理;而netty的主体功能此时就体现出来了,第一,实现了reactor线程模型,第二,封装很多网络通信中底层数据的处理逻辑,用户可以通过简单的调用或者继承即可实现相应的功能,从而屏蔽了网络通信底层逻辑的复杂性;




















