java - 在后台使用 Netty 与 Tomcat 时,Spring WebFlux 的差异

标签 java tomcat netty spring-webflux nonblocking

我正在学习 spring webflux,我已经阅读了以下系列文章(firstsecondthird)

在第三篇文章中,我遇到了以下文本:

Remember the same application code runs on Tomcat, Jetty or Netty. Currently, the Tomcat and Jetty support is provided on top of Servlet 3.1 asynchronous processing, so it is limited to one request per thread. When the same code runs on the Netty server platform that constraint is lifted, and the server can dispatch requests sympathetically to the web client. As long as the client doesn’t block, everyone is happy. Performance metrics for the netty server and client probably show similar characteristics, but the Netty server is not restricted to processing a single request per thread, so it doesn’t use a large thread pool and we might expect to see some differences in resource utilization. We will come back to that later in another article in this series.

首先,我没有看到该系列中较新的文章,尽管它是在 2016 年写的。我很清楚 tomcat 默认有 100 个线程来处理请求,一个线程同时处理一个请求,但我不明白短语 it is limited to one request per thread 是什么意思?

我还想知道 Netty 如何处理那个具体案例(我想了解与 Tomcat 的区别)。每个线程可以处理 2 个请求吗?

最佳答案

目前有 2 个基本概念来处理对 Web 服务器的并行访问,各有优缺点:

  1. 阻止
  2. 非阻塞

阻止网络服务器

阻塞、多线程 服务器的第一个概念是池中的线程数量有限。每个请求都将分配给特定的线程,并且该线程将被分配直到请求被完全服务。这与超市结账队列的工作方式基本相同,一次一个顾客,可能有平行线。在大多数情况下,Web 服务器中的请求在处理请求的大部分时间里都是 cpu 空闲的。这是因为它必须等待 I/O:读取套接字、写入数据库(基本上也是 IO)并读取结果并写入套接字。此外,使用/创建一堆线程很慢(上下文切换)并且需要大量内存。因此,这个概念通常不会非常有效地使用它拥有的硬件资源,并且对可以并行服务的客户端数量有硬性限制。此属性被滥用于所谓的饥饿攻击,例如slow loris ,一种通常单个客户端可以毫不费力地 DOS 大型多线程 Web 服务器的攻击。<​​/p>

总结

  • (+) 更简单的代码
  • (-) 并行客户端的硬限制
  • (-) 需要更多内存
  • (-) 通常的网络服务器工作硬件使用效率低下
  • (-) 易于DOS

大多数“传统”网络服务器都是这样工作的,例如较旧的 tomcat、Apache Web 服务器以及所有 Servlet 3 或 3.1 等旧版本。

非阻塞网络服务器

相比之下,非阻塞网络服务器可以只用一个线程为多个客户端提供服务。那是因为它使用 non-blocking kernel I/O features 。这些只是内核调用,当可以写入或读取某些内容时会立即返回并回调,从而使 cpu 可以自由地做其他工作。重用我们的超市比喻,这就像,当收银员需要他的主管解决问题时,他不会等待并阻塞整个 channel ,而是开始结账下一位顾客,直到主管到达并解决第一位顾客的问题客户。

这通常在事件循环或更高级的抽象中完成,如 green-threadsfibers .从本质上讲,这样的服务器不能真正并发处理任何事情(当然你可以有多个非阻塞线程),但它们能够并行服务数千个客户端,因为内存消耗不会随着时间的推移而扩展。与多线程概念一样彻底(阅读:最大并行客户端没有硬性限制)。也没有线程上下文切换。缺点是,非阻塞代码的读写通常更复杂(例如 callback-hell ),并且在请求执行大量 cpu 昂贵工作的情况下效果不佳。

总结

  • (-) 更复杂的代码
  • (-) cpu 密集型任务性能更差
  • (+) 作为网络服务器更有效地使用资源
  • (+) 更多没有硬限制(最大内存除外)的并行客户端

大多数现代“快速”网络服务器和框架促进了非阻塞概念:Netty、Vert.x、Webflux、nginx、servlet 3.1+、Node、Go 和 ASP.NET kestrel 网络服务器。

作为旁注,查看此基准页面,您会发现大多数最快的 Web 服务器通常都是非阻塞服务器:https://www.techempower.com/benchmarks/


另见

关于java - 在后台使用 Netty 与 Tomcat 时,Spring WebFlux 的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56794263/

相关文章:

javax.el.E​​LException : Provider com. 未找到 sun.el.E​​xpressionFactoryImpl

java - 使用 Async HTTP Client netty 客户端会在高负载下爆炸?

java - Netty:禁用自动读取对 `ByteToMessageDecoder` 不起作用?

java - 如何同时创建具有 Autowiring 和非 Autowiring 字段的构造函数?

java - Android:如何以编程方式确定 android 中的网络速度

java - 试图弄清楚如何最小化 ehcache 日志(n.s.e.constructs.web.filter.Filter)

java - 从 servlet 目录读取静态文件

java - 如何使用 Java netty 正确限制带宽使用?

java - Java文件批量下载

java - 获取连接超时: connect