Tomcat長連接是如何實現的


  瀏覽器在向服務器發送請求時,有的會帶上Connection:keep-alive參數,如下圖所示:

 

 

http1.1開始支持長連接。請求的頭部會帶上keep-alive參數。長連接的作用是減少斷開連接和重新連接的開銷,提高網絡請求效率。http只是1個協議規范,具體的實現請見下文。

TCP是由操作系統實現的。而socket是由JVM封裝的。所以java可以使用socket相關的api進行網絡請求操作。下面給出測試代碼:

erverSocket serverSocket  = new ServerSocket(8080, 1,  InetAddress.getByName(“localhost”));  
Socket socket = null;  
InputStream is = null;  
OutputStream os = null;  
try {  
    socket = serverSocket.accept();//1.監聽到客戶端的連接  
    is = socket.getInputStream();  
    os = socket.getOutputStream();  
    Request request = Util.getRequest(is);//2.從輸入流中讀取數據,並根據Http協議轉換成請求  
    Response response = Util.service(request);//服務器內部根據請求信息給出響應信息  
    os.writeResponse(response);//3.將響應信息寫到輸出流  
} catch (Exception e) {  
    e.printStackTrace();  
} finally {//4.關閉輸入輸出流及連接  
    if (is != null) {  
        is.close();  
    }  
    if (os != null) {  
        os.close();  
    }  
    socket.close();  
}  

后面的內容參考:https://www.jianshu.com/p/09e2f32a74dd  By飛行員舒克_ed03

按圖索驥研究tomcat

linux下tomcat的啟動我們只要運行startup.sh
我們研究下這個文件,其中的內容如下,運行startup.sh的實際結果是運行catalina.sh還帶了參數start

#
EXECUTABLE=catalina.sh
#
exec "$PRGDIR"/"$EXECUTABLE" start "$@"
接着我們看下catalina.sh,可以看到我們運行的java的入口類是org.apache.catalina.startup.Bootstrap,接着我們找Bootstrap源碼的main函數,main函數啟動項目,開啟端口,處於等待狀態。main還解析了tomcat的server.xml文件,進行初始化。tomcat的處理http協議的類是Http11Processor。這個類有個service方法。
方法中有個while循環,還有個keepAlive參數。其中有一段對keepalive的賦值改變
if (maxKeepAliveRequests == 1) {
    keepAlive = false;
 } else if (maxKeepAliveRequests > 0 && socketWrapper.decrementKeepAlive() <= 0) {
    keepAlive = false;
}

這里的maxKeepAliveRequests 就是server配置文件里的

web.xml
 <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443"
              maxKeepAliveRequests = 10000 />

這個參數的意思是最多經過多少個請求之后將Connection有keep-alive改為close的。
當keepAlive設為false以后,會退出循環並返回SocketState.CLOSED給調用者。調用者收到這個狀態后會關閉socket。結束連接,tcp會進行4次揮手結束會話。

假設keepAlive一開始就未設置,那么就不會進入循環,直接返回調用者SocketState.CLOSED。
如果keepAlive還沒到最大值,會一直在while的循環中,持續處理socket中的內容,直到keepAlive失效,或者連接中斷。

了解了原理之后,我們來看看我們的問題。keepAlive開啟會一直占用一個連接,直到socket關閉。tomcat有最大連接數參數是maxConnections,這個值表示最多可以有多少個socket連接到tomcat上。BIO模式下默認最大連接數是它的最大線程數(缺省是200),NIO模式下默認是10000,APR模式則是8192(windows上則是低於或等於maxConnections的1024的倍數)。如果設置為-1則表示不限制。當請求過多時,新的請求不會被接受,老的請求受網絡io的影響。但老的請求的會話被關閉的可能性還比較小。所以在搶票之類的程序中,先登入服務所在的tomcat還是有優勢的。從另一個方面來說關閉keepalive的功能對搶票人來說較公平。



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM