前言
可能很多 Java 程序員對 TCP 的理解只有一個三次握手,四次握手的認識,我覺得這樣的原因主要在於 TCP 協議本身稍微有點抽象(相比較於應用層的 HTTP 協議);其次,非框架開發者不太需要接觸到 TCP 的一些細節。其實我個人對 TCP 的很多細節也並沒有完全理解。
長連接與短連接
TCP 本身並沒有長短連接的區別 ,長短與否,完全取決於我們怎麼用它。
-
短連接:每次通信時,創建 Socket;一次通信結束,調用 socket.close()。這就是一般意義上的短連接,短連接的好處是管理起來比較簡單,存在的連接都是可用的連接,不需要額外的控制手段。
-
長連接:每次通信完畢後,不會關閉連接,這樣可以做到連接的複用。 長連接的好處是省去了創建連接的耗時。
連接的保活:KeepAlive
首先想到的是 TCP 中的 KeepAlive 機制。KeepAlive 並不是 TCP 協議的一部分,但是大多數操作系統都實現了這個機制(所以需要在操作系統層面設置 KeepAlive 的相關參數)。KeepAlive 機制開啓後,在一定時間內(一般時間爲 7200s,參數 tcp_keepalive_time)在鏈路上沒有數據傳送的情況下,TCP 層將發送相應的 KeepAlive 探針以確定連接可用性,探測失敗後重試 10(參數 tcp_keepalive_probes)次,每次間隔時間 75s(參數 tcp_keepalive_intvl),所有探測失敗後,才認爲當前連接已經不可用。
回憶七層網絡模型
我們已經爲應用層面的連接保活做了足夠的鋪墊,下面就來一起看看,怎麼在應用層做連接保活。
連接的保活:應用層心跳
終於點題了,文題中提到的 心跳 便是一個本文想要重點強調的另一個重要的知識點。上一節我們已經解釋過了,網絡層面的 KeepAlive 不足以支撐應用級別的連接可用性,本節就來聊聊應用層的心跳機制是實現連接保活的。
如何理解應用層的心跳?簡單來說,就是客戶端會開啓一個定時任務,定時對已經建立連接的對端應用發送請求(這裏的請求是特殊的心跳請求),服務端則需要特殊處理該請求,返回響應。如果心跳持續多次沒有收到響應,客戶端會認爲連接不可用,主動斷開連接。不同的服務治理框架對心跳,建連,斷連,拉黑的機制有不同的策略,但大多數的服務治理框架都會在應用層做心跳,Eureka 也不例外。
應用層心跳的設計細節
以 Eureka 爲例,支持應用層的心跳,客戶端會開啓Heartbeat timer,主要就是爲了給心跳做貢獻,eureka這裏叫做續約。
// Heartbeat timer
scheduler.schedule(
new TimedSupervisorTask(
"heartbeat",
scheduler,
heartbeatExecutor,
renewalIntervalInSecs,
TimeUnit.SECONDS,
expBackOffBound,
new HeartbeatThread()
),
renewalIntervalInSecs, TimeUnit.SECONDS);
關於client有兩項配置
# 該配置指示eureka客戶端需要向eureka服務器發送心跳的頻率 (Spring Cloud默認該配置是 30s)
eureka.instance.lease-renewal-interval-in-seconds: 10
# 該配置指示eureka服務器在接收到最後一個心跳之後等待的時間,然後才能從列表中刪除此實例 (Spring Cloud默認該配置是 90s)
eureka.instance.lease-expiration-duration-in-seconds: 30
還有一個問題client註冊的時候,是不是開啓了http層的keepalive呢,答案是沒有的。只是eureka在應用層上的心跳機制,保持連接,下圖就是jersey遠程註冊的時候看到的斷點信息,可見header中沒有加上,keepalive。
注意和 HTTP 的 KeepAlive 區別對待
-
TCP層的KeepAlive爲TCP層握手結束之後保持連接,其timeout爲TCP層握手結束之後能保持多長時間,如果在這個時間範圍內客戶端沒有數據傳輸,則關閉連接。
-
HTTP層的Keep-Alive爲HTTP層請求結束之後保持連接,其timeout爲HTTP層請求結束之後能保持多少時間,如果在這個時間範圍內客戶端沒有數據傳輸,則關閉連接。
這個eureka到底有沒有保持tcp的keepalive呢?還有有待考究。
參考連接:
TCP keepalive 和 http keep-alive: https://segmentfault.com/a/1190000012894416
Spring Cloud之Eureka客戶端健康檢測(五):https://blog.csdn.net/MrSpirit/article/details/80164315
Eureka的健康檢測機制:http://hyuga.top/2019/07/24/spring-cloud-eureka-health/
Eureka的工作原理以及它與ZooKeeper的區別:https://www.cnblogs.com/snowjeblog/p/8821325.html
深入理解Eureka之源碼解析:https://blog.csdn.net/forezp/article/details/73017664