亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在后臺使用 Netty 與 Tomcat 時 Spring webFlux 的差異

在后臺使用 Netty 與 Tomcat 時 Spring webFlux 的差異

富國滬深 2023-02-23 14:25:11
我正在學習 spring webflux 并且我已經閱讀了以下系列文章(第一,第二,第三)在第三篇文章中,我遇到了以下文本:請記住,相同的應用程序代碼在 Tomcat、Jetty 或 Netty 上運行。目前,Tomcat 和 Jetty 支持是在 Servlet 3.1 異步處理之上提供的,因此每個線程僅限于一個請求。當相同的代碼在 Netty 服務器平臺上運行時,該限制被解除,并且服務器可以同情地將請求分派給 Web 客戶端。只要客戶端不阻塞,大家都很高興。Netty 服務器和客戶端的性能指標可能顯示出相似的特征,但 Netty 服務器并不局限于每個線程處理單個請求,因此它不使用大型線程池,我們可能會看到資源利用方面的一些差異。我們稍后將在本系列的另一篇文章中回過頭來討論這一點。首先,我沒有看到該系列中的更新文章,盡管它是在 2016 年寫的。我很清楚 tomcat 默認有 100 個線程來處理請求,一個線程同時處理一個請求,但我沒有理解這句話it is limited to one request per thread是什么意思?我也想知道 Netty 如何處理那個具體案例(我想了解與 Tomcat 的區別)。每個線程可以處理 2 個請求嗎?
查看完整描述

2 回答

?
青春有我

TA貢獻1784條經驗 獲得超8個贊

目前有 2 個基本概念來處理對具有各種優點和缺點的 Web 服務器的并行訪問:

  1. 阻塞

  2. 非阻塞

阻止網絡服務器

阻塞、多線程的第一個概念服務器在池中有有限數量的線程。每個請求都將分配給特定的線程,并且該線程將被分配直到請求被完全服務。這與超市結賬隊列的工作方式基本相同,一次一個顧客,可能有平行線。在大多數情況下,Web 服務器中的請求在處理請求的大部分時間里都是 cpu 空閑的。這是因為它必須等待 I/O:讀取套接字、寫入數據庫(基本上也是 IO)并讀取結果并寫入套接字。此外,使用/創建一堆線程很慢(上下文切換)并且需要大量內存。因此,這個概念通常不會非常有效地使用它擁有的硬件資源,并且對可以并行服務的客戶端數量有硬性限制。slow loris,一種通常單個客戶端可以毫不費力地 DOS 大型多線程 Web 服務器的攻擊。

概括

  • (+) 更簡單的代碼

  • (-) 并行客戶端的硬限制

  • (-) 需要更多內存

  • (-) 通常的網絡服務器工作硬件使用效率低下

  • (-) 易于 DOS

大多數“傳統”網絡服務器都是這樣工作的,例如舊的 tomcat、Apache 網絡服務器以及所有Servlet早于 3 或 3.1 的東西等等。

非阻塞網絡服務器

相比之下,非阻塞網絡服務器可以只用一個線程為多個客戶端提供服務。那是因為它使用了非阻塞內核 I/O 特性。這些只是內核調用,當可以寫入或讀取某些內容時會立即返回并回調,從而使 cpu 可以自由地做其他工作。重用我們的超市比喻,這就像,當收銀員需要他的主管解決問題時,他不會等待并阻塞整個通道,而是開始結賬下一位顧客,直到主管到達并解決第一位顧客的問題顧客。

這通常在事件循環或更高的抽象中完成,如green-threadsfibers。本質上這樣的服務器不能真正并發處理任何事情當然你可以有多個非阻塞線程),但它們能夠并行服務數千個客戶端,因為內存消耗不會像多線程那樣急劇擴展概念(閱讀:最大并行客戶端沒有硬性限制)。也沒有線程上下文切換。缺點是,非阻塞代碼通常更難以讀寫(例如callback-hell),并且在請求執行大量 cpu 昂貴工作的情況下效果不佳。

概括

  • (-) 更復雜的代碼

  • (-) cpu 密集型任務的性能更差

  • (+) 作為 Web 服務器更有效地使用資源

  • (+) 更多沒有硬限制的并行客戶端(最大內存除外)

大多數現代“快速”網絡服務器和框架促進了非阻塞概念:Netty、Vert.x、Webflux、nginx、servlet 3.1+、Node、Go 網絡服務器。

作為旁注,查看此基準頁面,您會發現大多數最快的 Web 服務器通常都是非阻塞服務器: https: //www.techempower.com/benchmarks/


查看完整回答
反對 回復 2023-02-23
?
慕村9548890

TA貢獻1884條經驗 獲得超4個贊

使用 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。


查看完整回答
反對 回復 2023-02-23
  • 2 回答
  • 0 關注
  • 545 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號