文章目录
代码地址:https://github.com/JinZhengjuner/netty
1.BIO、NIO、AIO
1.1BIO(Blocking IO)
1.2 NIO
1.2.1 NIO入门班版本
同一时间没法支持太多的链接
资源紧张,线程切换多
1.2.2 NIO升级版,加入selector
selctor的创建会根据操作系统不同创建不同的selector,I/O多路复用底层主要用的Linux 内核函数epoll来实现(操作系统中断概念),Redis就是典型的基于epoll的NIO线程模型(nginx也是)
Linux man命令:打印出这个linux命令的描述
1.3 AIO(异步非阻塞)
基本不用这个AIO
同步意思链接accpet,接受数据都是自己干
- netty为什么不在aio的基础上开发?
在Linux系统上,AIO的底层实现仍使用Epoll,没有很好实现AIO,因此在性能上没有明显的优势,而且被JDK封装了一层不容易深度优 化,Linux上AIO还不够成熟。Netty是异步非阻塞框架,Netty在NIO上做了很多异步的封装。
2.Netty基础概念
NIO 的类库和 API 繁杂, 使用麻烦: 需要熟练掌握Selector、 ServerSocketChannel、 SocketChannel、
ByteBuffer等。
开发工作量和难度都非常大: 例如客户端面临断线重连、 网络闪断、心跳处理、半包读写、 网络拥塞和异常流的处 理等等。
Netty 对 JDK 自带的 NIO 的 API 进行了良好的封装,解决了上述问题。且Netty拥有高性能、 吞吐量更高,延迟更 低,减少资源消耗,最小化不必要的内存复制等优点。
2.1 Reactor响应式编程
2.2 ByteBuf
2.3 Netty编码解码
传输对象使用protostuff
2.4 Netty粘包拆包
黏包就是不同的消息合到一起了
拆包时大的被拆成小的了
Netty提供了多个解码器,可以进行分包的操作,一般使用长度,如下:
LineBasedFrameDecoder (回车换行分包)
DelimiterBasedFrameDecoder(特殊分隔符分包)
FixedLengthFrameDecoder(固定长度报文来分包)
一般也可以自定义,详情见代码
2.5 Netty心跳检测机制
长连接、短连接:长连接就是连接后不断开、
3.Netty核心
- 主从Reactor线程模型
- NIO多路复用非阻塞
- 无锁串行化设计思想
通过串行化设计,即消息的处理尽可能在同一个线程内完成,期间 不进行线程切换,这样就避免了多线程竞争和同步锁。
- 支持高性能序列化协议
- 零拷贝(直接内存的使用)
元空间用的也是堆外内存
直接内存申请较慢,但访问效率高。
分配直接内存,会判断直接内存是否充足,若不足,会进行一个fullGc(可能清楚掉使用直接内存的对象),若还是不足,会抛java.lang.OutOfMemoryError。 直接内存大小默认是和堆内存一样大,可通过-X:MaxDirectMemorySize=参数指定直接内存最大可分配空间
- ByteBuf内存池设计
内存不一定是连续的,对于需要较大的空间空间,可能很耗时