带你读《Apache Tomcat的云原生演进》——Tomcat的技术内幕和在喜马拉雅的实践(2)https://developer.aliyun.com/article/1377542
接下来做一个比较,看一看到底哪个更合适我们的业务场景使用。
NIO2和NIO相比,优势是连接一过来,它就可以主动去读这个数据,这样就减少了很多的注册和取消的事件。像NIO它就会先注册一个读事件,然后等数据来了,再把注册取消掉,最后交给后面的Catalina work线程处理这个请求。此外,它的性能模型更简单,它少了Poller线程。
NIO2和NIO相比,缺点是容易受慢客户端影响。刚开始有事件过来的时候,它用Poller线程来读,然后回调Catalina work线程让它继续读后面的数据。但是如果是没有Poller线程的情况下,body就会阻塞,而且这个时候是Catalina work线程。假如你设了100个线程值,但读body都阻塞了,那么后面Poller线段就会连接一个新的连接,然后提交一个任务到Catalina work线程来处理。但这个时候就会导致没有线程来处理新的连接事件的请求。
EPoll read 容易成为瓶颈。因为IO拷贝操作是poll线程的,所以如果是并发量比较大/body比较大的情况下,很容易使copy的进度比较慢,还可能会影响你的建连效率。
增加了复杂性。与NIO相比,它的复杂性确实增加了很多,它有各种的回调。因为它是通过异步模拟的NIO写代码的方式。
此外,还有一点,NIO2的文件发送没有基于应用操作系统这种零拷贝模式,直接通过操作系统发到连接缓存的channel里去。但还是用了普通的IO 把它读出来,然后再把它写到channel里面去。相比NIO反而增加了它拷贝的次数。
那么到底怎么选呢?
Tomcat 9和10默认的还是NIO。通过官方的配置我们也能看得出来,它建议的还是NIO。虽然切换次数减少了,系统调用次数减少,系统的切换减少了。但是性能在我们平时功能可能感觉不到,所以对于稳定还是NIO这种模式。
带你读《Apache Tomcat的云原生演进》——Tomcat的技术内幕和在喜马拉雅的实践(4)https://developer.aliyun.com/article/1377539