Discuss / Java / JAVA的服务是每收到一个请求就新开一个线程来处理吗?tomcat呢?

JAVA的服务是每收到一个请求就新开一个线程来处理吗?tomcat呢?

Topic source

Loading...

#1 Created at ... [Delete] [Delete and Lock User]

1.收到一个请求就处理,这个时候就不能处理新的请求,这种为阻塞

2.收到一个请求就新开一个线程去处理任务,主线程返回,继续处理下一个任务,这种为非阻塞。

类似2的模型,但是不是每次收到请求就开一个新的线程,而是使用线程池。不过,它依然是阻塞的。线程池的线程数量通常有限制的,如果所有线程都被阻塞(例如网速慢,或者被人恶意占用连接),那么接下来的请求将会排队等待。

上面说到的几种模型,都是基于BIO(阻塞IO)。
而NIO则是非阻塞IO,只需要一个线程或者少量线程,就可以处理大量请求。从性能上来说NIO实现的服务器并发性一般大于BIO,基于NIO的网络编程框架,例如Netty、MINA。

Tomcat运行可以选择BIO或者NIO模型,修改server.xml

<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" .../>
对tomcat来说,每一个进来的请求(request)都需要一个线程,直到该请求结束。tomcat会维护一个线程池,每一个http请求,会从线程池中取出一个空闲线程。默认初始化75个线程,可以进行修改。

问题:那么spring boot 环境下,tomcat的运行模式是哪种?

tomcat中提供了三种方式:BIO、NIO、APR。

BIO
tomcat7以下的版本都是BIO,就是一个请求是一个独立的线程。不能适用高并发的场景。

NIO
在8以上的版本,默认都是NIO

APR
APR是一种基于JNI的文件和网络读写模式,现在很多高版本的tomcat,都默认走它了。
SpringBoot默认是以 java -Xmx256m -Xss256k -jar xx.jar 来运行内置Tomcat启动方式默认是NIO

而廖大使用的这个内嵌的tomcat,默认走的应该是nio,因为启动时的线程名。

10:05:20.935 [http-nio-3000-exec-3] DEBUG org.springframework.web.context.request.async.WebAsyncManager - Started async request
10:05:20.936 [http-nio-3000-exec-3] DEBUG org.springframework.web.servlet.DispatcherServlet - Exiting but response remains open for further handling

暂时研究到这,想了解更深的同学,这里是美团一遍关于nio的解析文章。https://tech.meituan.com/2016/11/04/nio.html

突然想到这里好像和node很像。一直在讲node的单线程高并发。这个概念,到现在才有点感觉。以后再研究,现在的水平只能到这了


  • 1

Reply