问题汇总
1.服务端启动流程
2.客户端到服务端的心跳机制(服务端到客户端,客户端到服务端)
3.数据流转过程,状态转换机制4.ping pong
5.长连接和短连接
线程池所带来的问题
线程池的模型都是,一个线程往阻塞队列去放,线程池去队列里面take task,这个线程模型没法消除线程之间的切换引起的资源问题
netty EventLoop
netty EventLoop涉及到两个方面,一个是并发(多线程处理读写事件)和一个网络(网络的读写事件)。
netty4之前所有的线程模型:只保证输入(之前被称为upstream)event会在所谓的I/O线程中执行。所有输出(downstream)event被I/O或者其他任何线程处理。netty4:保证同一个线程的EventLoop处理一个Channel所有发生的事情,而netty3只保证输入是一个线程,不保证输出是同一个线程去处理。也就是一个event触发的事情不保证是同一个线程去处理,这样会带来线程之间的切换问题。
EventLoop模型:就是对于产生events事件,封装成task,给线程池进行调用
netty服务端启动流程
1.创建ServerBootstrap启动类
2.创建两个NioEventLoopGroup
实际上EventLoopGroup就是两个独立的Reactor线程池,一个用于接收客户端连接,一个用于处理I/O相关的的读写操作,或者执行系统task、定时任务等。
netty用于接收客户端请求的线程池职责:
1接收客户端连接
2将链路状态变更事件通知给ChannelPipeline
netty处理I/O操作的线程池职责:(理解下来就是对read事情感兴趣)
1.异步读取通信对端的数据报,发送读事件到ChannelPipeline
2.异步发送消息到通信对端,调用ChannelPipeline的消息发送接口
3.执行系统调用task
4.执行定时任务task
对比
1.创建当前的操作系统的selector,selector.open
2.创建serverSocketChannel
3.绑定端口
4.注册刚兴趣事件,socketChannel绑定到serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
5.selector轮询已经就绪的事件
netty也是对上面的几步进行封装,看看netty服务启动的过程
1.创建serverBootstrap
2.配置EventLoopGroup,也就是reactor线程池,一个用来接收客户端的连接,一个用来处理I/O事件
3.设置并绑定服务端 channel(NioServerSocketChannel)(指定IO类型,有NIO和BIO),也就是对应原生I/O创建serverSocketChannel
4.链路建立之后创建并初始化ChannelPipeline。ChannelPipeline本质就是负责网络事件流转,由ChannelHandler处理
5.ChannelPipeline初始化后之后,当然要设置ChannelHandler。比较实用的ChannelHandler包括系统编码、半包解码器、日志打印、SSL安全认证、链路空闲检测、Base64加解码
6.ServerSocketChannel设置好之后,开始绑定端口,注册到selector上
7.selector开始轮询就绪的Channel
8.取的就绪的Channel,在ChannelPipeLine中流转并通过ChannelHandler处理