java異步io
In this article, I am trying to explain the difference between Async-IO and Async-Request processing in the HTTP request in the Java world.
在本文中,我試圖解釋Java世界中HTTP請求中Async-IO和Async-Request處理之間的區別。
In the pre-Java 1.4 world, Java provides an API to send/receive data over the network socket. The original authors of JVM mapped this API behavior to OS socket API, almost one to one.
在Java 1.4之前的版本中,Java提供了一個API,用于通過網絡套接字發送/接收數據。 JVM的原始作者將此API行為幾乎一對一地映射到OS套接字API。
So, what is the OS socket behaviour? OS provides Socket programming api, which has send/recv blocking call. Since java is just a process running on top of linux(OS), hence this java program has to use this blocking api provided by OS.
那么,操作系統套接字的行為是什么? OS提供了Socket編程api ,該API具有send / recv 阻止調用 。 由于Java只是在linux(OS)之上運行的進程,因此該Java程序必須使用OS提供的此阻塞api。
The world was happy and java developers started using the API to send/receive the data. But they had to keep one java thread for every socket(client).
全世界都很高興,Java開發人員開始使用API??發送/接收數據。 但是他們必須為每個套接字(客戶端)保留一個Java線程。
Everybody was writing their own flavor of HTTP servers. Code sharing was becoming hard, the java world demanded a standardization.Enters the java servlet Spec.
每個人都在編寫自己的HTTP服務器。 代碼共享變得越來越困難,Java世界要求實現標準化。 輸入Java Servlet規范。
Before moving on lets define few terms:
在繼續之前,讓我們先定義幾個術語:
Java Server Developer: People who are using the java socket api and implementing http protocol like tomcat.
Java Server Developer :正在使用Java套接字api并實現諸如tomcat之類的http協議的人們。
java Application Developer: People who are building buisness application on top of tomcat.
Java應用程序開發人員:在Tomcat之上構建商務應用程序的人們。
GETTING BACK NOW
現在回來
Once the java servlet spec entered the world, it said:
Java Servlet規范進入世界后,它說:
Dear java server developers, please provide a method like below:
尊敬的Java服務器開發人員,請提供以下方法:
doGet(inputReq, OutPutRes)
so that java application developer can implement doGet
and they can write their business logic. Once “application developer” wants to send the response
, he can call OutPutRes.write().
這樣Java應用程序開發人員就可以實現doGet
并編寫自己的業務邏輯。 一旦“應用程序開發人員”想要發送response
,他就可以調用OutPutRes.write().
A thing to Note:Since socket api is blocking, hence OutPutRes.write() is also blocking. Also, the additional limitation was that the response object is committed on doGet method exit.
注意事項:由于套接字api被阻塞,因此OutPutRes.write()也被阻塞。 另外,另一個限制是響應對象在doGet方法退出時提交。
Due to these limitations, people had to use one thread for processing one request.
由于這些限制,人們不得不使用一個線程來處理一個請求。
Time passed and the internet took over the world. one Thread per Request started to show limitations.
時間流逝,互聯網占領了世界。 每個請求一個線程開始顯示限制。
問題一: (Problem 1:)
The thread-per-request model fails when there are long pauses during the processing of each request.
當每個請求的處理過程中出現長時間的停頓時,每個請求線程模型將失敗。
For Example: fetching data from sub-service take long time.
例如:從子服務中獲取數據需要很長時間。
Under such a situation, the thread is mostly sitting idle and JVM can run out of thread easily.
在這種情況下,線程通常處于空閑狀態,JVM可以很容易地用完線程。
問題2: (Problem 2:)
Things got even worse with http1.1 persistent connection. As with persistent connection, the underlying TCP connection will be kept alive and the server has to block one thread per connection.
使用http1.1持久連接,情況變得更糟。 與持久連接一樣,基礎TCP連接將保持活動狀態,并且服務器必須為每個連接阻止一個線程。
But why does the server have to block one thread per connection?
但是,為什么服務器必須為每個連接阻塞一個線程?
But why does the server have to block one thread per connection?Since OS provides a blocking socket Recv api, the jvm has to call the OS blocking Recv method in order to listen for more requests on same tcp connection from the client.
但是,為什么服務器必須為每個連接阻塞一個線程? 由于OS提供了阻塞套接字Recv api,因此jvm必須調用OS阻塞Recv方法,以便在來自客戶端的同一tcp連接上偵聽更多請求。
世界要求解決方案! (The world demanded a solution!)
The First Solution came from the creator of JVM. They introduced NIO(ASYNC-IO). Nio is the non-blocking API for sending/receiving data over socket.
第一個解決方案來自JVM的創建者。 他們介紹了NIO( ASYNC-IO ) 。 Nio是用于通過套接字發送/接收數據的非阻塞API。
Some background: the OS along with blocking socket api also provides a non-blocking version of the socket api.
一些背景: 操作系統以及阻止套接字api也提供了套接字api的非阻止版本。
But how does the OS provide that .. Does it fork a thread internally and that thread gets blocked???
但是,操作系統如何提供該功能呢?它是否在內部派生了一個線程并且該線程被阻塞了?
The ANSWER is no… the OS instruct the hardware to interupt when there is data to read or write.
答案不是……當有數據需要讀取或寫入時,操作系統會指示硬件中斷。
NIO allowed the “java server developer” to tackle problem 2 of blocking one thread per TCP connection. With NIO being an HTTP persistent connection, the thread does not require it to block on recv call. Instead, it can now process it only when there is data to be processed. This allowed one thread to monitor/handle a large number of persistent connections.
NIO允許“ java服務器開發人員” 解決問題2 : 每個TCP連接阻塞一個線程 。 由于NIO是HTTP持久連接,因此該線程不需要它在recv調用時阻塞。 相反,它現在只能在有要處理的數據時進行處理。 這允許一個線程監視/處理大量持久連接。
The Second Solution came from servlet spec. Servlet Spec got an upgrade and they introduced async support (Async Request Processing).
第二個解決方案來自servlet規范。 Servlet Spec進行了升級,并引入了異步支持 (異步請求處理)。
AsyncContext acontext = req.startAsync();
IMPORTANT: This upgrade removed the limitation of committing the response object on doGet method completion.
重要說明: 此升級消除了在doGet方法完成時提交響應對象的限制。
This allowed the “Java Application Developer” to tackle Problem 1, by offloading work to background threads. Now instead of keeping the thread waiting during the long pause, the thread can be used to handle other requests.
這樣,“ Java應用程序開發人員”就可以通過將工作卸載到后臺線程來解決問題1 。 現在,可以使線程不必處理長時間的暫停,而可以使用該線程來處理其他請求。
結論: (CONCLUSION:)
Async-IO in java is basically using the non-blocking version on OS socket API.
Java中的Async-IO基本上在OS套接字API上使用非阻塞版本。
Async request processing is basically the servlet spec standardization of how to process more requests with one thread.
異步請求處理基本上是servlet規范中的一個規范,該規范規定了如何通過一個線程處理更多請求。
參考資料: (REFERENCES:)
https://www.scottklement.com/rpg/socktut/tutorial.pdfhttps://stackoverflow.com/questions/15217524/what-is-the-difference-between-thread-per-connection-vs-thread-per-request
https://www.scottklement.com/rpg/socktut/tutorial.pd f https://stackoverflow.com/questions/15217524/what-is-the-difference-between-thread-per-connection-vs-thread-每個請求
Motivation of article: Team Learning/Knowledge Sharing
文章動機:團隊學習/知識共享
翻譯自: https://www.freecodecamp.org/news/java-async-io-async-request-processing-in-http-request-1a04f395d8c7/
java異步io