簡體   English   中英

如何在不關閉 TCP 連接的情況下關閉處理 TCP 請求的線程?

[英]How do you close threads handling TCP requests without closing the TCP connection?

我遇到了下面的線程,並想為請求而不是客戶端連接實現線程,但我不確定如何在不關閉每個 TCP 傳輸之間的客戶端連接的情況下這樣做。 我看到了下面的內容,但不確定如何保持我的服務器和客戶端之間的 TCP 連接處於活動狀態,而無需為該連接保持線程處於活動狀態。

最佳答案指定:“請注意,每個請求的線程並不意味着框架必須關閉 HTTP 請求之間的 TCP 連接”我很想看看這是如何完成的。

每個連接的線程與每個請求的線程有什么區別?

@aholbreich

您標記了 TCP 但包含的鏈接提到了 HTTP 的東西。 我假設您的意思是在 HTTP 上下文中提出您的問題,或者讓我們假設 TCP 之上的通用請求/回復協議。

關於這一點:

請注意,每個請求的線程並不意味着框架必須關閉 HTTP 請求之間的 TCP 連接

在連接上處理 IO 的線程策略通常取決於您執行 IO 的方式。 如果您要阻塞 IO,則每個連接必須(至少)一個線程。 這意味着您至少有一個線程 99% 的時間在read()上被阻塞。

如果您在這種情況下,則無需為每個請求追求 1 個線程,除非您想同時服務多個請求。 如果是這種情況,您需要為每個請求生成一個新線程來handle請求(即產生響應)。 新的按請求線程位於您用來處理 IO(讀/寫)到底層連接的線程之上。 在您產生響應的某個時刻,您必須將其發送回執行 IO 的線程之一。 (請注意,在 HTTP1.1 中,雖然可以重用連接來發送多個請求,但在單個連接上一次只能有一個未完成的請求......所以如果你已經在做,最終每個請求都不需要一個線程每個連接 1 個線程)。 對於具有多路復用的 HTTP2 而言,情況並非如此。

在這種情況下,有很多if s 並使其值得。

這樣做的問題是創建線程是一項昂貴的操作。 僅當由於計算而產生響應需要很長時間(即您受 CPU 限制)或產生響應的行為需要阻塞 IO 時,這樣做才有意義。 但那時......我不會首先使用阻塞 IO 來處理連接(即我會放棄 1 線程 <-> 1 連接的想法。

我的直覺是你把兩個不同的東西混為一談:

  1. 執行實際的 IO(從套接字讀取和寫入)。
  2. 在服務器中執行“處理”特定消息並最終產生響應的實際業務邏輯。

就個人而言,事先沒有太多了解,一個安全的選擇是使用Netty之類的東西來處理 IO(用於非阻塞 IO 的多線程事件循環),然后將長請求或阻塞請求處理卸載到固定大小的線程池。

阻塞本身並不是壞事,當它浪費操作系統資源時就不好了。 未來免責聲明:當Loom項目登陸 JDK 時,我認為阻塞 API 的使用將會重新出現,並且該領域的實踐將會發生一些變化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM