背景
1. “点”(知识点)
i/o模式支持(io有数据就绪和数据读取两阶段)
bio 同步阻塞(排队打饭,等待,自己取)mysql客户端使用,避免大量连接,保护mysql服务器;适用于客户端
nio(点单、等待被叫,不等待,自己取)netty中使用,可以切换;适用大量客户端在线的场景,且单个请求包不要太大;适用于服务端
aio(包厢,不等待,送过来)
同步与异步:(异步是接收方处理数据的返回)
在数据传输阶段,如果发起网络调用的线程还可以做其他事情,我们称之为异步,否则称之为同步。异步I/O则无需自己负责进行读写
阻塞与非阻塞:(是否需要等待)
在等待数据阶段,如果发起网络调用后,在服务端数据没有准备好的情况下客户端会阻塞,我们称为阻塞 IO;如果数据没有准备好,但网络调用会立即返回,我们称之为非阻塞 IO。
菜好了,谁端-> 数据就绪后,数据操作谁完成?
数据就绪后需要自己去读是同步,数据就绪直接读好再回调给程序是异步。
nio:通过io线程池来管理多个客户端连接,事件选择就绪通道,丢到业务线程池处理
支持三种Reactor线程模型
单Reactor单线程 (一个人【线程】包揽所有:迎宾【接入连接】、点菜【请求】、做饭【业务处理】、上菜【响应】、送客【断开连接】)
单Reactor多线程模式(多招几个伙计:大家一起做上面的事情)
主从Reactor多线程模式(进一步分工:搞一个或者多个人专门做迎宾)
一个进程多个连接(io多路复用,select) + 线程池(处理事件) = reactor(I/O 多路复用统一监听事件,收到事件后分配(Dispatch)给某个进程。)
netty两次编解码
1.解决粘包半包
io.netty.handler.codec.LengthFieldBasedFrameDecoder
2.序列化对象方便存储和传输(Google Protobuf),需要跨语言,速度快,够小
io.netty.handler.codec路径下
keepalive
传输层:tcp连接 keepalive,时间比较长(确保电话能通)
应用层:(确保电话有人接听,例如服务不过来)
idle(电话通了后,订餐的说了一堆订餐要求,说着说着,对方就不讲话了。一般你会稍微等待一定的时间,在这个时间内看看对方还会不会说话(Idle 检测),如果还不说,认定对方存在问题(Idle),于是开始发问“你还在么?”(keepalive),)
和keepalive结合使用
netty开启keepalive:bootstrap.childOption(NioChannelOption.of(StandardSocketOptions.SO_KEEPALIVE), true)
锁
内存使用
减少对像本身大小(基本类型而非包装类,使用类变量)
对分配内存进行预估 (动态内存分配、伙伴算法和Slab 算法)
零拷贝
堆外内存
内存池
高性能的数据结构(看)
FastThreadLocal
HashedTimerWheel