`
5452
  • 浏览: 28040 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

关于阻塞IO和非阻塞IO在应用服务器的应用

阅读更多
传统的阻塞I/O为每个请求分配一个工作线程,这个工作线程负责请求的整个过程的处理,包括从网络读取请求数据、解析参数、计算或调用其他的业务逻辑、编码结果并将其返回给请求者,然后这个线程将返回到线程池中供其他线程复用。Tomcat 5采用的这种方式在应对完美的网络环境、简单的逻辑以及小量的并发用户时是非常高效的。

但如果请求包括了复杂的逻辑、或需要和外部的系统(例如文件系统、数据库或消息服务器)进行交互时,工作线程在其处理的大部分时间都会处于等待同步的调用或网络传输返回的状态中,这个阻塞的线程会被请求持有直到请求处理完毕,但操作系统需要暂停线程来保证CPU能够处理其他的请求,如果客户端和服务器端的网络状况不太好的话,网络的延时会导致线程被阻塞更长时间,在更糟的状况下,当需要keep-alive的话,当前的工作线程会在请求处理完毕后阻塞很长一段时间,在这样的情况下,为了更好的使用CPU,就必须增加更多的工作线程了。

Tomcat采用了一个线程池,每个请求都会被线程池中一个空闲的线程进行处理。"maxThreads"表示Tomcat 能创建的处理请求的最大线程数。如果我们把"maxThreads"设置的太小的话,就不能充分的使用CPU了,更为重要的是,随着并发用户的增长,会有很多请求被服务器抛弃和拒绝。在此次测试中,我们将"maxThreads"设置为了1000(这对于Tomcat来说有些太大了),在这样的设置下,当并发用户增长到较高数量时,Tomcat会创建很多的线程。大量的Java线程会导致JVM和OS忙于执行和维护这些线程,而不是执行业务逻辑处理,同时,太多的线程也会消耗更多的JVM heap内存(每个线程堆栈需要占用一些内存),并且会导致更为频繁的gc。

Glassfish不需要这么多的线程,在非阻塞IO中,一个工作线程并不会绑定到一个特定的请求上,如果请求被某些原因所阻塞,那么这个线程将被其他的请求复用。在这样的方式下,Glassfish可以用几十个工作线程来处理几千的并发用户。通过限制线程资源,非阻塞IO拥有了更好的可扩展性,这也是Tomcat 6采用非阻塞IO的原因了。
  

这个是我在blogjava上看到的一篇文章的一部分,解答了我以前的一个疑惑,转过来以备回查。
原帖地址:http://www.blogjava.net/BlueDavy/archive/2008/07/07/213179.html
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics