这样的话 在高并发环境下 岂不是需要很多线程? 感觉不对啊
1
ewBuyVmLZMZE 2017-02-28 07:40:13 +08:00
Just read the book: How tomcat works
|
2
guoliang 2017-02-28 08:20:18 +08:00 via iPhone
可以读读这篇 netflix 关于性能调优的帖子: http://techblog.netflix.com/2015/07/tuning-tomcat-for-high-throughput-fail.html?m=1
|
3
Cbdy 2017-02-28 08:21:22 +08:00 via Android
粒子群 actor : akka 、 erlang
单线程 reactor : node.js 、 vert.x 多线程 thread pool : fastcgi 、 servlet 多进程: cgi 另这和 tomcat 其实关系不大,是 servlet 标准有相关说明,另外,较新的 serglet 标准支持异步,类似 reactor 。既然 po 有质疑,请问有更好的并发模型吗?说出来分享一下 |
4
kaneg 2017-02-28 11:01:11 +08:00
基于 Java 的,八九不离十都是线程池,线程池大小是可配置的。当然,线程池的大小要和最大的请求数量要协调,否则谁都扛不住。
|
5
esolve OP |
6
Cbdy 2017-02-28 17:53:36 +08:00
@esolve 我可能解释的不是很清楚,是的,每个请求一个线程去处理。 tomcat 实现的是 servlet 标准——很经典的线程池模型。 但线程不可能一直加上去,否则切换线程开销会剧增,系统会抖动,性能会下降。所以一般会丢请求。
|
7
esolve OP @Cbdy 还是没懂,丢请求?那怎么高并发?
如果 10 万个请求同时来,线程只能开 1000 个,那 9 万多个请求都被丢掉? |
9
gam2046 2017-02-28 19:56:22 +08:00
相信楼主上网有的时候会看到服务器返回 503 Service Unavailable ,此时页面刷新一下就一切正常仿佛没发生过一样。这就有可能(只是有可能)是因为服务器的前端处理器并发量达到了线程池的上限,此时就不再接受新的请求。直接告诉客户端服务不可用。
其次....tomcat 其实并发量也不会很大(相比静态服务端而言),毕竟所有东西都要到容器里转一圈,再经过用户代码。这一圈下来资源开销就已经很大了。 |
10
SoloCompany 2017-03-01 00:00:13 +08:00
@esolve #7 这个结论明显不正确,还是先读一下资料吧,至少先搞懂 BIO / NIO / AJP 几种不同的 io 模型,还有 sendfile 。
对于 BIO 而言,也许是正确的,因为 socket 成了最大的瓶颈。所有其它 IO 模型都是异步模型,超过处理能力的请求只会排队, poller 线程(连接及 header 处理)是独立的; sendfile (比如静态文件)还完全不会占用 worker 线程 |
11
esolve OP @SoloCompany 我知道阻塞 非阻塞 select poll 等
我只是针对 servlet 和 tomcat 的状况 我只是想知道是不是一个 jsp 页面的 http request 对应一个线程调用 servlet 的 service () 如果是的,那么假如千万用户同时打开千万个 jsp 页面,那是不是同时千万线程? |
12
SoloCompany 2017-03-01 04:03:00 +08:00
@esolve 脱离谈响应时间谈并发就是耍流氓,难道你用 nodejs 单线程服务就能解决问题了?好好想想这句话是什么意思。多线程不是让问题更加恶劣,而是缓解问题,如果不存在阻塞(典型的是 IO 阻塞),最简单的多线程模型显然是最优解,所有异步框架都是为了解决阻塞问题的。
|
13
esolve OP @SoloCompany 我没看懂你在说什么。。。
我不是来求问解决方案的 我是来探讨 概念和原理的。。。 我是想知道是不是一个 jsp 页面的 http request 对应一个线程调用 servlet 的 service () 如果是的,那么假如千万用户同时打开千万个 jsp 页面,那是不是同时千万线程? |
14
SoloCompany 2017-03-01 13:40:57 +08:00 via iPhone
@esolve 既然大家不住一个频道上,那就按你想象中的来吧,不再回复了
|
15
haochih 2017-03-01 16:22:50 +08:00
Tomcat 假如在未分布式情况,按照 Servlet 标准,未实现 SingleThreadModel 的 Servlet ,如果只声明一次的话,该 Servlet 在服务过程中只会有一个实例,当客户端有请求发起时, Servlet 容器会给每一个请求,从 Servlet 容器维护的线程池(具体线程个数参数配置)里面获取一个线程为其服务( BIO 模型下)。当有大量的请求发起时,线程池里面的线程可能会一下子被用完,这时候剩余请求就会被排在请求队列中(具体可以排多少个,参数配置),等有线程闲下来时继续服务排队请求,假如请求数量超过了最大的排队数,未排进队列的请求就会不予处理。
按照楼主说的, 10w 个 HTTP Request ,不会有 10w 个线程同时服务, Servlet 容器线程池配置了最多 1000 个线程,那么一瞬间这 1000 个线程将会服务于 1000 个请求,假如剩余 9000 个中 2000 个又排进了待处理队列,那么剩下的 7000 个将会不予处理,当然这是同一时间点 10w 个请求同时到达的情况。实际情况下, 10w 个请求到达时间应该有前有后,所以可能某些请求达到时,某些请求已经被迅速处理掉,线程闲下来可以继续处理了。 @SoloCompany 想请教一下上面这段在 BIO 模型下理解是否正确,谢谢。 |
16
SoloCompany 2017-03-01 16:26:41 +08:00
@haochih #15 这个描述无论是在 BIO NIO 还是 APR 下应该都是正确的, BIO 并不是不能处理高并发, BIO 只是无法处理 keepalive (socket accept 也是专用线程来的不会占用 worker 线程) 以及无法支持 sendfile 而已
|
17
haochih 2017-03-01 16:37:36 +08:00
@SoloCompany 谢谢点拨,对 IO 模型学习还不够,将继续学习。
|
18
esolve OP @haochih 您好,我想请问一下,如果不是在 BIO 下,例如在 NIO 下,状况是怎样的?在 NIO 下,不是一个 http request 对应一个线程了吗?
|
20
haochih 2017-03-01 21:45:36 +08:00
@esolve 嗯,在 NIO 模型下,也是一个请求对应地必须要有一个线程去处理,但 NIO 模型比 BIO 模型线程利用效率要高,其中就有#16 提到的 keep-avlie 请求。
|
21
esolve OP |