簡體   English   中英

為什么Tomcat的非阻塞連接器使用阻塞套接字?

[英]Why Tomcat's Non-Blocking Connector is using a blocking socket?

我正在閱讀非阻塞I / O,java NIO和tomcat連接器,查看了tomcat的NIO Connector的代碼,並NioEndpoint.bind()找到了這個

serverSock.configureBlocking(true); //mimic APR behavior

我沒有NIO的經驗,所以有人可以解釋當套接字配置為阻塞時它是如何非阻塞的嗎?

看起來在此次提交中引入了以下行:https://github.com/apache/tomcat/blob/bd8122700c2e70e5adbaddcd289fb1a974f981fe/java/org/apache/tomcat/util/net/NioEndpoint.java

據我所知,NioEndpoint正在使用阻塞ServerSocketChannel來阻止和等待傳入連接,並且只有在接受它之后才以非阻塞方式處理這個傳入套接字通道(請參閱setSocketOptions方法)。

使得ServerSocketChannel成為非阻塞的替代方法將導致作者指出忙讀 - 即線程將不斷輪詢傳入連接,因為非阻塞模式下的accept()可能返回null。

你可以在這里找到一些有用的解釋。

PS我認為神秘的APR代表Apache Portable Runtime。

看完代碼后:

serverSock對象正在偵聽傳入連接是否阻塞 與其新接受的連接關聯的socket通道對象是實現非阻塞 I / O的對象。

作為偵聽傳入連接的線程的Acceptor class在其run方法中具有以下定義:

protected class Acceptor extends AbstractEndpoint.Acceptor {
        @Override
        public void run() {
            // Loop until we receive a shutdown command
            while (running) {
                // Loop if endpoint is paused
                while (paused && running) {
                   ...
                try {
                        ........
                    SocketChannel socket = null;
                    try {
                        // Accept the next incoming connection from the server
                        // socket
                        socket = serverSock.accept(); 

                    } catch (IOException ioe) {............}
                ...................
                // setSocketOptions() will add channel to the poller
                // if successful
                if (running && !paused) {
                    if (!setSocketOptions(socket)) {
                        countDownConnection();
                        closeSocket(socket);
                    }
                } ....

正如您所看到的那樣,它是處理新socketsetSocketOptions方法,它具有以下代碼:

protected boolean setSocketOptions(SocketChannel socket) {
        // Process the connection
        try {
            //disable blocking, APR style, we are gonna be polling it
            socket.configureBlocking(false);
            Socket sock = socket.socket();
            socketProperties.setProperties(sock); 

與用於在相應連接的端點中發送/接收數據的每個連接相關聯的socket通道對象是真正實現non-blocking I/Osocket通道對象。

盡管可以始終將serverSock對象accept方法設置為非阻塞,但我認為將select (即accept)操作設置為非阻塞是不切實際的,並且不會服務於任何實際目的,並且在任何實際上下文中都不會有用。 我想不出任何非阻塞接受操作有用的用例。 那對我來說。

從呼叫者的角度看非阻塞。 API仍然需要使用阻塞(在工作線程中)或異步I / O來實際完成操作。 否則,套接字將需要一個自旋鎖,並產生CPU浸泡。

您需要查看實現的其余部分,以了解如何完成此映射。

暫無
暫無

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

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