每个连接使用线程池的线程是如何工作的

3

我正在使用Spring Boot和嵌入式Tomcat(8),在app.prop文件中我们有两个选项:

server.tomcat.max-connections = 1000
server.tomcat.max-threads= 20

我从Tomcat文档中了解到,第一个选项是服务器可以处理的最大连接数,第二个选项是Tomcat线程池中的最大线程数。在此之后,我明白了,连接和请求不是我以为的同一个词。接着,我阅读了这个主题

什么是每个连接线程与每个请求线程的区别?

该主题的主要观点如下:

Thread per request will create a thread for each HTTP Request the server receives

Thread per connection will reuse the same HTTP Connection from multiple requests

在“重用相同的HTTP连接”这句话之后,我查看了Http keep-alive。
概念:在响应后,服务器和客户端能够保持开放的连接。
但是这是如何实现的呢?我的意思是,当我向服务器发送请求时,线程池中的一个线程将接收我的请求,然后向我发送一个请求。根据“Http keep-alive”的规定,我的连接不会关闭。它存储在哪里?当我发送另一个请求时会发生什么?是否同一个线程会处理我的请求?
2个回答

2
所以这个问题是我3年前发布的。那时我不明白线程数与连接数的区别。这对于初学Java开发者来说真的很困惑,因为Java在用户级线程上提供了一个抽象层,并且在此上下文中连接是什么并不清楚。
因此,在基于Unix的系统中,连接数是服务器同时可以打开的文件描述符的总数。假设连接数为100,线程数为10。这意味着当用户向服务器发送请求时,服务器会为此请求创建一个文件描述符,如果所有Tomcat的线程都忙,则该文件描述符将在有空闲线程时立即处理。为了打开多个文件描述符,Tomcat(8+)使用基于事件循环的NIO连接器。这里的主要点是Tomcat有一个(这个数字是可配置的)线程监听传入请求,创建相关的文件描述符,并在服务器完成处理后使用文件描述符将响应发送给客户端。
顺便说一句,这就是Nodejs在幕后的工作原理,如果您感兴趣,我写了一篇关于它的博客文章 https://strogiyotec.github.io/pages/posts/io.html

-1
它存储在哪里?
那是一个实现细节 - 对于在Tomcat之上开发应用程序来说无关紧要。你需要查阅Tomcat的源代码才能了解这个问题,但我认为这完全没有必要。除非你想进入tomcat开发领域,否则它不会教你任何东西。对于应用程序:忽略它。
当我发送另一个请求时会发生什么?
它将被处理。就这样。
同一个线程是否会处理我的请求?
不会的。或者随机地是的。任何当前空闲的线程都将用于处理此请求。
您的问题暗示了一些危险的期望: 在请求处理中,除了将处理成你的servlet的request和response对象所封装的所有当前状态之外,您不能假设任何其他事情。不能作出任何其他假设-事实上,任何其他假设(例如关于线程、servlet的成员变量)通常都是错误的。
容器(tomcat)能够很好地隔离您的应用程序与那些低级细节。不要进去乱搞。您除了在requestresponse对象中找到的内容以外,不能对处理一个请求和下一个请求之间的任何一致性做出任何假设。

如果你不深入了解细节,如何调整应用程序的性能以处理高负载?Tomcat公开了一堆参数,正是为了这个原因。 如果你不理解某些术语/概念,你将无法对任何东西进行微调。 如果我漏掉了什么,请告诉我。 - Rushil Paul
应用程序调优不依赖于哪个线程处理哪个请求 - 这完全无关紧要。想象一下,处理您之前请求的线程现在正在通过缓慢的连接提供100M的下载 - 您肯定不希望等待它。这就是我在答案中提到的方面。是的,性能调优是一件事,但不,它不在这个层面上。连接和处理该连接上请求的线程是完全独立的。而且这很好。 - Olaf Kock

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接