在微服務架構里,服務發(fā)現(xiàn)幾乎是每個請求的“第一站”。想象一下,用戶點個按鈕下單,結果卡在服務查找上半秒,體驗立馬打折。這種延遲積少成多,輕則頁面發(fā)愣,重則接口超時。優(yōu)化服務發(fā)現(xiàn)延遲,不是錦上添花,而是系統(tǒng)流暢運行的基本功。
緩存機制:別每次都重新查
服務地址不會每秒都變,但很多客戶端卻每次調用前都去注冊中心拉一遍列表。這就像每天上班都重新查一遍公司地址,其實記住一次就夠了。引入本地緩存,設置合理的過期時間(比如30秒),能大幅減少網(wǎng)絡往返。
service-discovery:
cache-ttl: 30s
refresh-interval: 20s
像 Nacos、Eureka 的 SDK 默認都有緩存策略,但默認值未必適合你的場景。高并發(fā)下可以適當延長刷新間隔,降低注冊中心壓力。
監(jiān)聽代替輪詢:主動通知更高效
有些老系統(tǒng)還在定時輪詢注冊中心,比如每5秒問一次“有更新嗎”。這種方式不僅延遲高,還浪費資源?,F(xiàn)代服務發(fā)現(xiàn)組件都支持事件監(jiān)聽,服務上線或下線時,注冊中心主動推消息過來。
以 Consul 為例,使用 long polling 可以實現(xiàn)近乎實時的更新:
curl "http://consul:8500/v1/health/service/payment?wait=5m&index=12345"
只要服務狀態(tài)有變,連接立刻返回新數(shù)據(jù),延遲從幾秒降到毫秒級。
DNS 緩存調優(yōu):別讓系統(tǒng)自己拖后腿
用了 Kubernetes?那很可能走的是 DNS 做服務發(fā)現(xiàn)。但 JVM 默認會緩存 DNS 永久不失效,一旦 Pod 重建 IP 變了,老連接就全斷了。得在啟動時加上:
-Dsun.net.inetaddr.ttl=10 -Dsun.net.inetaddr.negative.ttl=2
把緩存時間壓到10秒內,既避免頻繁解析,又不會僵住。
就近發(fā)現(xiàn):物理距離決定響應速度
跨機房調用服務,延遲動不動上百毫秒。通過標簽(label)和權重策略,讓服務優(yōu)先發(fā)現(xiàn)本機房的實例。Kubernetes 的 topologyKey 就能實現(xiàn):
topologyKeys:
- "kubernetes.io/hostname"
- "topology.kubernetes.io/zone"
先找本節(jié)點,再找同可用區(qū),層層兜底,響應自然更快。
預熱與健康檢查:別讓新實例冷啟動拖累整體
新服務剛啟動,還沒準備好就被流量打進來,不僅自己扛不住,還會讓調用方超時。注冊前加個就緒檢查,確保依賴加載完成、數(shù)據(jù)庫連通再注冊自己。
同時,在發(fā)布前預熱連接池,提前建立好與其他服務的連接通道,避免第一波請求卡在建連上。