我记得2年前或3年前读过几篇文章,人们声称现代线程库变得如此好,以至于每个请求线程服务器不仅比非阻塞服务器更容易编写,而且速度也更快。 。我相信这甚至在Java中使用JVM进行了演示,该JVM将Java线程映射到pthread(即Java nio的开销大于上下文切换的开销)。
但是现在我看到所有“尖端”服务器都使用异步库(Java nio,epoll甚至node.js)。这是否意味着异步获胜?
最佳答案
我认为不是。如果两个模型都实现良好(这是BIG的要求),我认为应优先考虑NIO的概念。
核心是计算机。无论您做什么,都无法比拥有内核更多地并行化应用程序。也就是说,如果您拥有4核计算机,则一次只能做4件事(我在这里掩盖了一些细节,但这足以满足您的要求)。
扩展这种思想,如果您拥有的线程多于内核,那么您就会浪费。这种浪费有两种形式。首先是额外线程本身的开销。其次是在线程之间切换所花费的时间。两者都可能很小,但是它们在那里。
理想情况下,每个内核有一个线程,并且这些线程中的每个线程都在其内核上以100%的处理速度运行。理想情况下不会发生任务切换。当然有操作系统,但是如果您使用16核计算机,并为操作系统留出2-3个线程,则其余的13-14会用于您的应用程序。这些线程可以切换它们在您的应用程序中执行的操作,例如当它们被IO要求阻止时,而不必在操作系统级别上支付这些费用。将其直接写入您的应用中。
在SEDA http://www.eecs.harvard.edu/~mdw/proj/seda/中可以看到这种缩放的一个很好的例子。与标准的“每请求线程数”模型相比,它在负载下显示了更好的伸缩性。
我的个人经验是在Netty。我有一个简单的应用程序。我在Tomcat和Netty中都很好地实现了它。然后,我对100个并发请求进行了负载测试(我认为最多为800个)。最终,Tomcat变慢了爬行速度,并表现出极其突发/缓慢的行为。 Netty的实现只是增加了响应时间,但继续以令人难以置信的总体吞吐量进行。
请注意,这取决于可靠的实现。随着时间的推移,NIO仍在不断改善。我们正在学习如何调整服务器操作系统以使其更好地工作,以及如何实现JVM以更好地利用操作系统功能。我认为尚不能宣布获胜者,但我相信NIO将是最终的获胜者,而且已经做得不错。