1.IO模型:

用户线程发起IO调用后经历的流程:
1.CPU在用户态执行应用程序的代码
2.从用户态切换到内核态,执行内核代码
3.内核检测到IO设备上的数据未就绪时,将进程的task_struct结构体从运行队列中移到等待队列,并让出CPU时间片(此刻即发生阻塞);
4.当数据准备就绪,内核将数据从IO设备缓存区拷贝至内核空间,接着将进程的task_struct结构体重新移到运行队列,这样进程就有机会重新获得CPU时间片。
5.内核将数据从内核空间拷贝至用户空间,系统调用返回,CPU又从内核态切换到用户态,访问用户空间的数据。
IO时内核的关键两步:
1.用户线程等待内核将数据从网卡拷贝到内核空间。 --->决定是否阻塞
2.内核将数据从内核空间拷贝到用户空间(应用进程的缓冲区)。--->决定同步异步。
关于阻塞/非阻塞及同步/异步
1.阻塞或非阻塞:指应用程序在发起I/O操作时,是立即返回还是等待
2.同步和异步:指应用程序在与内核通信时,数据从内核空间到应用空间的拷贝,是由内核主动发起还是由应用程序来触发。
3种IO模型
BIO(同步阻塞式IO):每个请求都会创建一个线程,对性能开销大,不适合高并发场景。优点是稳定,适合连接数目小且固定架构。
NIO(同步非阻塞式IO):基于多路复用选择器监测连接状态再同步通知线程处理,从而达到非阻塞的目的。有比较好的并发量,当前使用最为普遍。
AIO (异步非阻塞式IO):请求处理线程执行完成进行回调通知,继续执行后续操作。
调优选择
1.I/O调优实际上是连接器类型的选择,一般情况下默认都是NIO(Linux未异步I/O)。
2.如果使用TLS 加密传输,可以考虑 APR,因为APR通过OpenSSL 来处理TLS握手和加密/解密。OpenSSL本身用C语言实现,它还对TLS通信做了优化,所以性能比Java要高。
3.如果Windows部署,且并发量较高,可以考虑NIO.2(因为Windows从操作系统层面实现了异步I/O)。
2.线程池

Tomcat线程池的扩展
当前线程数大于核心线程数、小于最大线程数,并且已提交的任务个数大于当前线程数时,会创建线程。即:线程不够用时,优先创建线程,而不是入队列。
Tomcat在线程总数达到最大数时,不是立即执行拒绝策略,而是再尝试向任务队列添加任务,添加失败后再执行拒绝策略。
3.关键指标

4.主要调优参数
protocol
org.apache.coyote.http11.Http11NioProtocol - non blocking Java NIO connector
org.apache.coyote.http11.Http11Nio2Protocol - non blocking Java NIO2 connector
org.apache.coyote.http11.Http11AprProtocol - the APR/native connector
maxThreads
最大线程数,默认:200
minSpareThreads
核心线程数,默认:10