Tomcat中BIO和NIO的区别(Tomcat)

BIO

Tomcat中BIO的模型和理论很简单,例图如下

1.Acceptor线程死循环阻塞接收客户端的打过来的socket请求

2.接收到请求之后打包成一个SocketProcessor(Runnable),扔到线程池中读取/写入数据

参数配置

1.Acceptor默认线程是1,可以设置参数自己去改

2.Executor的线程池,一个Connector对应一个线程池,一个线程池可以被多个Connector公用,最小线程数是10,最大线程数是200

BIO总结

**1.**如果请求量很大,那么可以适当提高Acceptor线程池的线程数量

2.如果是那种处理起来效率不高的请求,那么可以适当提高Executor中的线程数

3.线程池中的线程还是要根据线上实际情况设置的,并不是越多越好,自己去压测看一下,找一个适当的值

NIO

Tomcat7中的NIO其实只有在读取请求头和请求行下才是非阻塞的,Servlet读取请求体的时候依旧还是阻塞的。执行流程如下

1.Acceptor接收客户端连接,接收到之后将socketChannel推到一个Poller(本质上也是一个Runnable)的events队列中,客户端和服务端的交互就此结束

2.推入到events队列中的是一个注册事件(要将其绑定到对应Poller中的Selector中)

3.对应Poller中的线程会去循环查询Selector中是否有事件发生,在查询之前会现将Events中的注册事件执行了,所以在执行events队列中的事件时,就相当于将socketChannel注册到Selector中。

4.socketChannel中的读写事件被Poller轮询到,就会socketChannel和读写事件打包成一个SocketProcessor,然后扔到Executor中执行读写逻辑

5.当SocketProcessor中的线程运行时,就会从socketChannel中读取/写入数据时(非阻塞),如果发现请求行和请求头已经读写并且解析完了,那么就会将剩下的交给Servlet处理,Servlet中可能会读写数据,或者发起响应,Servlet的这两个操作都是阻塞的。如果SocketProcessor线程读取到了数据,但是发现请求行和请求头的数据还没有读完,那么本次请求直接结束,要处理的话只能等下一次就绪事件

6.tomcat7中读取请求体的时候其实依旧是阻塞的,因为tomcat7本身并没有非阻塞这个概念,servlet读取请求体时底层依旧是用inputStream.read()方法读取,并且是阻塞的

7.Servlet读取请求体inputStream.read()方法底层调用的是InternalNioInputBuffer.SocketInputBuffer.doRead(),在这个方法中会调用fill(param1,param2)方法从操作系统读取数据

8.阻塞读取数据流的时候,还是得利用Selector,因为刚开始的时候socketChannel会被设置成非阻塞,然后socketChannel会被注册到一个Selector(称为主Selector),然后你如果再想把他改成阻塞,是会报错的(NIO中的限制),tomcat中为了实现这个阻塞,又构造了一个辅助Selector,将socketChannel重新注册到辅助Selector上,并设置成阻塞(在此之前已经取消了对主Selector的绑定)

9.首先先InputStream.read(),然后加锁(为了实现阻塞),辅助Selector也有与之对应的Poller线程,也会去轮询辅助Selector上发生的就绪事件。一旦轮询到对应的事件,就会解锁,解阻塞

10.从socketChannel中读取数据,结束

NIO总结

Tomcat7中的NIO其实相对于BIO并没有太多的性能提升,只是可以接收更多的客户端请求(NIO直接推到Events队列中就直接返回了),真正的在处理请求的时候并没有体现出太大的优势,如果是那种不用处理请求数据,并且不用响应什么数据的那种请求,那么NIO会有非常好的吞吐量

相关推荐
神明不懂浪漫12 小时前
【第五章】Java中的继承与多态
java·开发语言
AI多Agent协作实战派14 小时前
AI多Agent协作系统实战(十七):凌晨4点,我的AI系统在“假装工作“——3个bug同时爆炸的5小时
java·前端·bug
gaolei_eit14 小时前
Java+Ai+vue
java·spring·maven
qq_25183645714 小时前
基于java Web 动漫视频网站毕业论文
java·开发语言·前端
LayZhangStrive14 小时前
JUC相关的函数、注解、变量杂记
java·面试·多线程·juc
未秃头的程序猿14 小时前
给公司做了个AI客服Agent,用的Spring AI 1.0,3天上线领导拍板了
java·后端·ai编程
曹牧14 小时前
Eclipse 批量文本替换
java·ide·eclipse
程序员清风14 小时前
OpenAI官方发布最新提示词技巧!
java·后端·面试
一只枫林14 小时前
MySQL内、外连接知识点汇总
java·前端·数据库
梅头脑14 小时前
写了3年CRUD,volatile和synchronized的区别还是答不清——直到我画出了这张三性两锁边界图
java