作為java的初學者,看了網上的資料後,關于java的長短連接配接,感覺了解的不是很深刻,結合自己的學習和網上的資料整理如下,不正确之處請大家批評指正。
其實作為java語言本身而言,能夠提供給我們使用的最終的網絡接口實際也就是java的socket api,除此外别無他物。 是以我們經常提到的http和netty 長短連接配接實際都是針對的java socket而言的,大家都學過網絡的7層模型,但是在java中7層模型顯的過于的複雜,大多數的層,我們無法直接感覺。實際簡化為如下的圖是較為準确的:
http的長短連接配接:
何為http長連接配接,準确的說http是無狀态的連接配接,每一次請求完畢後,實際用戶端和伺服器端在應用層是沒有任何連接配接的,也就是所謂的每一次請求建立一次連接配接,無狀态的,但是為什麼還有http長連接配接之說呢?那是因為http作為應用層的協定其實際依賴的是底層的tcp協定,tcp協定大家都非常的熟悉也就是三次握手的可靠連接配接,可以多次可靠的傳遞ip資料包。是以在http的協定中,有一個屬性是:connection:keep-alive,設定了該屬性則是浏覽器告訴伺服器請使用http長連接配接方式,實際也就是tcp長連接配接,也就是浏覽器實際和伺服器之間在完成一次http請求後并沒有真正的關閉底層socket連接配接,下一次的請求還是繼續的使用這個連接配接。
以tomcat為例子,實際tomcat 在htpp長連接配接方式下,當一個新的http請求來臨則打開一個socket處理請求完畢後,tomcat并沒有立即調用java 關閉socket的方法關閉連接配接,而是維持了這個連接配接,當然此時如果浏覽器關閉了,那這個tcp鍊路也就關閉了(關于如何維持一個tcp連接配接不中斷,這個超出的本文的讨論範圍,隻需要記住隻要沒有顯式去關閉已建立的socket連接配接,則保持着tcp的連接配接)。大家知道網絡資源也是很珍貴的,是以tomcat不能一直維持着這個連接配接,當上次請求時間大于使用者設定的session 有效時間到來時,則會主動關閉這個連接配接,這個時間是可以設定的。當然也可以不設定這個字段,那實際就是告訴伺服器,請每次建立連接配接,一次請求後則直接關閉,這種情況是相當的耗費資源的,實際也就是http的短連接配接。tomcat等都是預設的tcp長連接配接。
java nio的長短連接配接:
java的nio 大家都非常的熟悉了,基于nio的netty等傳輸協定也是非常的多,這些架構都号稱實作了長連接配接,實際其依賴的網絡底層依舊是java的socket 接口。其實也就是在傳輸的過程中,java的socket并沒有随着資料傳輸的完成而關閉,而是一直維持着這個tcp的連接配接,等下次使用依舊使用這個連接配接(同上,關于如何維持tcp的長連接配接超出的本文的讨論範圍)。而以netty為例子,是支援使用者指定初始化方式的,即類似于http,可以設定是使用長連接配接還是短連接配接。
附:
關于底層是如何維持tcp長連接配接的,可以參考《tcp/ip詳解》一書,有詳細的介紹。總之就是伺服器和用戶端之間建立一個探測心跳,不斷的偵斷對方是否依舊存在,如果沒有收到對方的回報資訊,可以認為對方的連接配接已經斷了,那麼伺服器會考慮關閉tcp連接配接,如果對方在一定的時間又發送了偵斷資訊,則認為又連接配接上了。
總之,通過tcp的長連接配接,維持了一個對應用層透明的鍊路,應用層可以反複的使用這個鍊路傳輸資料,而儲存高效,避免了三次握手建立連接配接和四次握手關閉連接配接所帶來的資源浪費和資源消耗。