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会有非常好的吞吐量

相关推荐
心态特好41 分钟前
详解WebSocket及其妙用
java·python·websocket·网络协议
Haooog2 小时前
98.验证二叉搜索树(二叉树算法题)
java·数据结构·算法·leetcode·二叉树
武子康2 小时前
Java-143 深入浅出 MongoDB NoSQL:MongoDB、Redis、HBase、Neo4j应用场景与对比
java·数据库·redis·mongodb·性能优化·nosql·hbase
jackaroo20202 小时前
后端_基于注解实现的请求限流
java
道可到2 小时前
百度面试真题 Java 面试通关笔记 04 |JMM 与 Happens-Before并发正确性的基石(面试可复述版)
java·后端·面试
飞快的蜗牛3 小时前
利用linux系统自带的cron 定时备份数据库,不需要写代码了
java·docker
聪明的笨猪猪3 小时前
Java Spring “IOC + DI”面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
ThisIsMirror3 小时前
CompletableFuture并行任务超时处理模板
java·windows·python
珹洺4 小时前
Java-Spring入门指南(二十一)Thymeleaf 视图解析器
java·开发语言·spring
源码集结号4 小时前
一套智慧工地云平台源码,支持监管端、项目管理端,Java+Spring Cloud +UniApp +MySql技术开发
java·mysql·spring cloud·uni-app·源码·智慧工地·成品系统