gst*_*low 2 java tomcat nonblocking netty spring-webflux
我是springwebflux的学习者,并且阅读了以下系列文章(第一,第二,第三篇)
在第三条中,我面对以下案文:
请记住,相同的应用程序代码可以在Tomcat,Jetty或Netty上运行。当前,在Servlet 3.1异步处理的基础上提供了Tomcat和Jetty支持,因此,每个线程只能有一个请求。当相同的代码在Netty服务器平台上运行时,约束解除,服务器可以同情地向Web客户端分发请求。只要客户不阻拦,每个人都会很高兴。Netty服务器和客户端的性能指标可能显示相似的特征,但是Netty服务器不限于每个线程处理单个请求,因此它不使用大型线程池,并且我们可能希望看到资源利用率方面的一些差异。在本系列的另一篇文章中,我们将回到后面。
首先,我看不到该系列的新文章,尽管该文章写于2016年。对我来说,很明显,tomcat默认具有100个线程来处理请求,一个线程同时处理一个请求,但我没有理解短语,它限制为每个线程一个请求是什么意思?
我也想知道Netty如何在具体情况下工作(我想了解与Tomcat的区别)。每个线程可以处理2个请求吗?
pat*_*ckf 30
目前有 2 个基本概念来处理对 Web 服务器的并行访问,它们具有各种优点和缺点:
阻塞的第一个概念,多线程服务器在池中具有有限数量的线程。每个请求都将被分配给特定的线程,并且该线程将被分配,直到请求被完全服务。这与超级市场中结账队列的工作方式基本相同,一次一个顾客可能有平行线。在大多数情况下,Web 服务器中的请求在处理请求时的大部分时间将处于 cpu-idle 状态。这是因为它必须等待 I/O:读取套接字,写入数据库(基本上也是 IO)并读取结果并写入套接字。此外,使用/创建一堆线程很慢(上下文切换)并且需要大量内存。因此,这个概念通常不会非常有效地使用它所拥有的硬件资源,并且对可以并行服务的客户端数量有严格的限制。慢loris,一种攻击,通常单个客户端可以毫不费力地对大型多线程Web服务器进行DOS攻击。
大多数“传统”网络服务器都以这种方式工作,例如较旧的 tomcat、Apache Webserver 以及Servlet早于 3 或 3.1 的所有内容等。
相比之下,非阻塞 Web 服务器可以只用一个线程为多个客户端提供服务。那是因为它使用了非阻塞内核 I/O 特性。这些只是内核调用,当可以写入或读取某些内容时,它们会立即返回并回调,从而使 cpu 可以自由地做其他工作。再次使用我们的超市比喻,这就像,当收银员需要他的主管解决问题时,他不会等待并阻塞整个车道,而是开始结账,直到主管到达并解决第一个问题顾客。
这通常在事件循环或更高的抽象中完成,如green-threads或Fibers。本质上,这样的服务器不能真正并发地处理任何事情(当然你可以有多个非阻塞线程),但它们能够并行地为数千个客户端提供服务,因为内存消耗不会像多线程那样急剧扩展概念(阅读:最大并行客户端没有硬性限制)。也没有线程上下文切换。缺点是,非阻塞代码读取和写入通常更复杂(例如callback-hell),并且在请求执行大量 CPU 昂贵的工作的情况下不能很好地执行。
大多数现代“快速”网络服务器和框架都促进了非阻塞概念:Netty、Vert.x、Webflux、nginx、servlet 3.1+、Node、Go Webservers。
作为旁注,查看此基准测试页面,您将看到大多数最快的网络服务器通常是非阻塞的:https : //www.techempower.com/benchmarks/
使用Servlet 2.5时,Servlet容器会将请求分配给线程,直到该请求已被完全处理。
使用Servlet 3.0异步处理时,服务器可以在应用程序处理请求时在单独的线程池中分派请求处理。但是,当涉及到I / O时,工作总是在服务器线程上进行,并且总是阻塞。这意味着“慢速客户端”可以垄断服务器线程,因为服务器在通过不良网络连接读取/写入该客户端时被阻塞。
使用Servlet 3.1,允许异步I / O,在这种情况下,不再使用“一个请求/线程”模型。任何时候都可以在服务器管理的不同线程上安排位请求处理。
Servlet 3.1+容器通过Servlet API提供了所有这些可能性。应用程序可以利用异步处理或非阻塞I / O。在非阻塞I / O的情况下,范式更改非常重要,使用起来确实具有挑战性。
使用Spring WebFlux-Tomcat,Jetty和Netty没有完全相同的运行时模型,但是它们都支持反应性背压和非阻塞I / O。
| 归档时间: |
|
| 查看次数: |
1382 次 |
| 最近记录: |