有贊 TCP 網絡編程最佳實踐

圖片

作者:飄石

部門:技術中臺 / 中間件

概述

本文是根據有贊中間件團隊多年的 TCP 網絡編程實踐經驗總結而來,目的是爲了避免應用因各種網絡異常而出現各種非預期行爲,從而造成非預期的影響,影響系統穩定性與可靠性。

本文不會涉及 TCP 的各個基礎知識點,主要是總結一些 TCP 網絡編程實踐中可能碰到的一些問題,以及相應的經過實踐驗證的解決方案等。雖然本文檔很多細節主要是針對於 Linux 系統,不過,大部分建議適合於所有系統。

本文共總結了 16 項建議,下面逐一進行介紹。

  1. 服務端監聽設置 SO_REUSEADDR 選項

當我們重啓服務端程序的時候可能會碰到 “address already in use” 這樣的報錯信息,即地址已被使用,導致程序無法快速成功重啓。老的進程關閉退出了,爲什麼還會報地址已被使用呢?

我們先來理解如下兩點:

我們先簡單回顧一下 TCP 連接關閉過程中的 TIME_WAIT 狀態,如下所示:

(圖片來源:Wikipedia)

TIME_WAIT 存在的意義主要有兩點:

  1. 維護連接狀態,使 TCP 連接能夠可靠地關閉。如果連接主動關閉端發送的最後一條 ACK 丟失,連接被動關閉端會重傳 FIN 報文。因此,主動關閉方必須維持連接狀態,以支持收到重傳的 FIN 後再次發送 ACK。如果沒有 TIME_WAIT,並且最後一個 ACK 丟失,那麼此時被動關閉端還會處於 LAST_ACK 一段時間,並等待重傳;如果此時主動關閉方又立即創建新 TCP 連接且恰好使用了相同的四元組,連接會創建失敗,會被對端重置。

  2. 等待網絡中所有此連接老的重複的、走失的報文消亡,避免此類報文對新的相同四元組的 TCP 連接造成干擾,因爲這些報文的序號可能恰好落在新連接的接收窗口內。

因爲每個 TCP 報文最大存活時間爲 MSL,一個往返最大是 2*MSL,所以 TIME_WAIT 需要等待 2MSL。

當進程關閉時,進程會發起連接的主動關閉,連接最後會進入 TIME_WAIT 狀態。當新進程 bind 監聽端口時,就會報錯,因爲有對應本地端口的連接還處於 TIME_WAIT 狀態。

實際上,只有當新的 TCP 連接和老的 TCP 連接四元組完全一致,且老的迷走的報文序號落在新連接的接收窗口內時,纔會造成干擾。爲了使用 TIME_WAIT 狀態的端口,現在大部分系統的實現都做了相關改進與擴展:

因此,在開啓了 TCP timestamps 擴展選項的情況下(net.ipv4.tcp_timestamps = 1),可以放心的設置 SO_REUSEADDR 選項,支持程序快速重啓。

注意不要與 net.ipv4.tcp_tw_reuse 系統參數混淆,該參數僅在客戶端調用 connect 創建連接時才生效,可以使用 TIME_WAIT 狀態超過 1 秒的端口(防止最後一個 ACK 丟失);而 SO_REUSEADDR 是在 bind 端口時生效,一般用於服務端監聽時,可以使用本地非 LISTEN 狀態的端口(另一個端口也必須設置 SO_REUSEADDR),不僅僅是 TIME_WAIT 狀態端口。

  1. 建立並遵守應用監聽端口規範

每個應用、每個通信協議要有固定統一的監聽端口,便於在公司內部形成共識,降低協作成本,提升運維效率。如對於一些網絡 ACL 控制,規範統一的端口會給運維帶來極大的便利。

應用監聽端口不能在 net.ipv4.ip_local_port_range 區間內,這個區間是操作系統用於本地端口號自動分配的(bind 或 connect 時沒有指定端口號),Linux 系統默認值爲 [32768, 60999]。現在一個應用服務器實例(無論是 VM 還是 K8S Pod 等),本地不僅僅會包含應用進程自身,還可能會包括監控採集、sidecar 代理等進程。如果選了 net.ipv4.ip_local_port_range 這個範圍內的端口作爲監聽端口,你的應用進程啓動前,對應的端口很可能已經被自動分配給其他進程的 TCP 連接,就會導致監聽端口綁定失敗,從而導致進程啓動失敗;當然,如果已經分配的端口設置了 SO_REUSEADDR 也不會導致你的應用監聽端口綁定失敗,但這些臨時端口一般都不會設置 SO_REUSEADDR。如果確實有需求監聽 net.ipv4.ip_local_port_range 區間內的端口(如保留三方系統的默認端口),可以設置 net.ipv4.ip_local_reserved_ports 系統參數進行預留,預留的端口不會被自動分配出去;但這樣會給運維增加系統的交付難度,所以,一般不建議這樣做。

有讚的 net.ipv4.ip_local_port_range 系統值設置爲 [9000, 65535],並且對所有類型的應用、通信協議監聽端口都進行了統一規範,監聽端口都小於 9000。

  1. 應用服務端口與管理端口分離

服務端口即業務請求的處理端口,管理端口爲框架或應用的管理請求處理端口(如服務註冊上線、下線)。以 Spring Boot 爲例,應用端口對應 server.port,管理端口對應 management.port。

應用的服務端口與管理端口分離有如下意義:

有贊線上曾經碰到過一個問題:一個 Dubbo 業務應用提供 HTTP 服務和 Dubbo 服務,HTTP 服務端口與 HTTP 管理端口是同一個,該應用的一個實例因內部邏輯問題發生了死鎖,造成請求阻塞超時,但這時服務註冊的健康保活線程仍然正常,所以該異常服務實例還是在線的,客戶端仍在發送請求到該實例。這時想將該實例進行服務註冊下線操作但保留進程以便排查問題,但由於業務線程阻塞導致 HTTP 線程池所有線程阻塞,進而導致管理模塊無線程可處理 HTTP 服務註冊下線請求,最終無法正常下線。有贊 Dubbo 框架已經對應用服務端口與管理端口進行了分離,並進行了線程池隔離,避免再出現類似的問題。當然,熔斷等其他機制也有助於應對個別實例異常問題,這裏我們主要關注端口分離問題。

  1. 建立連接設置超時時間

網絡擁塞、IP 不可達、握手隊列滿時,都可能會導致建立連接阻塞與超時,爲了避免不可控的阻塞時間對應用造成難以預知的影響,建議在建立連接時設置超時時間,進行超時控制。如果沒有主動進行設置,超時時間是由系統默認行爲進行控制的,而系統的默認行爲肯定是無法滿足所有應用場景的。(注:握手隊列滿時,如果設置了系統參數 net.ipv4tcp_abort_on_overflow,連接會立刻被重置)

我們看一下系統默認是如何控制連接建立超時時間的?

TCP 三次握手的第一個 SYN 報文沒有收到 ACK,系統會自動對 SYN 報文進行重試,最大重試次數由系統參數 net.ipv4.tcp_syn_retries 控制,默認值爲 6。初始 RTO 爲 1s,如果一直收不到 SYN ACK,依次等待 1s、2s、4s、8s、16s、32s 發起重傳,最後一次重傳等待 64s 後放棄,最終在 127s 後纔會返回 ETIMEOUT 超時錯誤。

建議根據整個公司的業務場景,調整 net.ipv4.tcp_syn_retries 系統參數進行兜底。有贊將該參數設爲 3,即最大 15s 左右可返回超時錯誤。

  1. 使用應用層心跳對連接進行健康檢查

當 TCP 連接有異常時,我們需要儘快感知到,然後進行相應的異常處理與恢復。對於 FIN 或 RST 這種連接關閉、重置場景,應用層是可以快速感知到的。但是對於對端機器掉電、網線脫落、網絡設備異常等造成的假連接,如果沒有特殊措施,應用層很長時間都感知不到。

提到網絡異常檢測,大家可能首先想到的是 TCP Keepalive。系統 TCP Keepalive 相關的三個參數爲 net.ipv4.tcp_keepalive_time、net.ipv4.tcp_keepalive_intvl、net.ipv4.tcp_keepalive_probes,默認值分別爲 7200s、75s、9,即如果 7200s 沒有收到對端的數據,就開始發送 TCP Keepalive 報文,如果 75s 內,沒有收到響應,會繼續重試,直到重試 9 次都失敗後,返回應用層錯誤信息。

爲什麼需要實現應用層的心跳檢查呢?系統的 TCP Keepalive 滿足不了需求嗎?是的,系統的 TCP Keepalive 只能作爲一個最基本的防禦方案,而滿足不了高穩定性、高可靠性場景的需求。原因有如下幾點:

對於 TCP 狀態無法反應應用層狀態問題,這裏稍微介紹幾個場景。第一個是 TCP 連接成功建立,不代表對端應用感知到了該連接,因爲 TCP 三次握手是內核中完成的,雖然連接已建立完成,但對端可能根本沒有 Accept;因此,一些場景僅通過 TCP 連接能否建立成功來判斷對端應用的健康狀況是不準確的,這種方案僅能探測進程是否存活。另一個是,本地 TCP 寫操作成功,但數據可能還在本地寫緩衝區中、網絡鏈路設備中、對端讀緩衝區中,並不代表對端應用讀取到了數據。

這裏重點解釋一下 TCP KeepAlive 與 TCP 重傳的衝突問題。Linux 系統通過 net.ipv4.tcp_retries2 參數控制 TCP 的超時重傳次數,即影響 TCP 超時時間。初始 RTO 爲 TCP_RTO_MIN(200ms),RTO 進行指數退讓,最大 RTO 爲 TCP_RTO_MAX(2min),net.ipv4.tcp_retries2 默認爲 15,大概 924.6s 超時。詳細重傳次數、RTO、超時時間關係,如下表所示。

v1nDDT

如果 TCP 發送緩衝區中有數據未發送成功,TCP 會進行超時重傳,而不會觸發 TCP Keepalive。也就是說,即使應用設置了很小的 TCP Keepalive 參數,如 time=10s、interval=10s、probes=3,在 net.ipv4.tcp_retries2 默認配置下,可能還是一直等到 15min 左右才能感知到網絡異常。可能有的人不理解爲什麼 Keepalive 會被重傳干擾,其實這裏就是個優先級的問題。TCP 最大重傳次數的作用高於 Keepalive 參數的作用,未達到最大重傳次數,不會嚮應用層報告網絡錯誤信息。如果 Keepalive 不受重傳影響,同樣也會對關注重傳的人造成干擾,比如爲什麼還沒達到最大重傳次數就放棄重傳並關閉連接了?我們可以通過 netstat -ot 或 ss -ot 命令查看當前連接的計時器信息。

建議根據實際情況調低 net.ipv4.tcp_retries2 參數。RFC 1122 建議對應的超時時間不低於 100s,即至少爲 8,有贊系統該參數默認爲 10。

因此,想實現一個網絡健壯的應用,應用層心跳必不可少。對於 HTTP2、gRPC、Dubbo 等協議都支持心跳,如果是基於這些協議開發的應用,可以直接使用這些協議的特性來實現應用層心跳。

實現應用層心跳需要考慮如下點:

  1. 連接重連需要增加退讓與窗口抖動

當網絡異常恢復後,大量客戶端可能會同時發起 TCP 重連及進行應用層請求,可能會造成服務端過載、網絡帶寬耗盡等問題,從而導致客戶端連接與請求處理失敗,進而客戶端觸發新的重試。如果沒有退讓與窗口抖動機制,該狀況可能會一直持續下去,很難快速收斂。

建議增加指數退讓,如 1s、2s、4s、8s...,同時必須限制最大退讓時間(如 64s),否則重試等待時間可能越來越大,同樣導致無法快速收斂。同時,爲了降低大量客戶端同時建連並請求,也需要增加窗口抖動,窗口大小可以與退讓等待時間保持一致,如: nextRetryWaitTime = backOffWaitTime + rand(0.0, 1.0) * backOffWaitTime

在進行網絡異常測試或演練時,需要把網絡異常時間變量考慮進來,因爲不同的時長,給應用帶來的影響可能會完全不同。

  1. 服務端需要限制最大連接數

一個服務端口,理論上能接收的最大 TCP 連接數是多少呢?TCP 四元組中的服務端 IP、服務端端口已經固定了,理論上的上限就是客戶端可用 IP 數量 * 客戶端可用端口數量。去除一些 IP 分類、端口保留等細節,理論上限就是 2^32 * 2 ^16 = 2^48。

當然,目前現實中肯定達不到理論上限的瓶頸。一個 TCP socket 所關聯的主要資源有內存緩衝區、文件描述符等,因此,實際限制主要取決於系統內存大小與文件描述符數量限制。

服務端限制最大連接數,主要有兩個目的:

每個 TCP 連接的 socket 都佔用一個 FD,每個進程以及整個系統的 FD 數量都是有限制的。Linux 系統下,通過 ulimit -n 可以查看單個用戶的進程運行打開的 FD 最大數量,通過 cat /proc/sys/fs/file-max 可以查看所有進程運行打開的最大 FD 數量,如果不符合應用的需求,那就需要進行相應的調整。

達到 FD 上限會有什麼影響呢?首先,肯定是無法接收新 TCP 連接了;其次,除了 TCP 連接佔用的 FD 外,你的應用肯定還有內部場景佔用或需要分配新的 FD,比如日誌文件發生輪轉創建新日誌文件時,如果日誌文件創建失敗,對於依賴本地存儲的應用(如 KV、MQ 等存儲型應用),就導致服務不可用了。所以,要在系統限制的基礎上,根據應用的特性預留一定數量的 FD,而不能把所有的 FD 都給客戶端 TCP 連接使用。

有贊在線上壓測時,一個應用就碰到過類似的一個問題。壓測期間,壓力比較高,導致磁盤 IO 壓力增高,請求處理延遲增高,導致客戶端超時。客戶端發現超時關閉連接,創建新連接重試,但此時服務端由於 IO 阻塞帶來的延遲並未能夠及時回收連接關閉(CLOSE_WAIT)的 socket 以及 FD,導致 FD 消耗越來越多,最終導致 FD 耗盡,新日誌文件創建失敗,而該應用又是存儲類型應用,強依賴於日誌落盤,最終導致服務不可用。

除了服務端限制最大連接數外,如果應用有對應的客戶端 SDK,最好也在客戶端 SDK 也做一層保護。

  1. 儘量不要依賴中心化四層負載均衡器

LVS 是一個經典的中心化四層負載均衡解決方案,也有各種雲廠商提供的類似 LVS 的產品,原理大多是一致的。它們的優點這裏我們就不談了。使用該類方案可能會面臨如下問題:

建議通過分佈式的動態服務註冊與發現以及客戶端負載均衡來替代中心化負載均衡方案,如微服務架構中的服務註冊、服務發現、負載均衡等解決方案。

在不得不使用中心化負載均衡器的場景下,也需要注意以下問題:

有贊線上環境曾多次碰到過 LVS 引起的相關問題,也正在研發分佈式的四層代理。

  1. 警惕大量 CLOSE_WAIT

先介紹曾經碰到的一個問題。線上環境告警提示有服務器發生較高的 TCP 重傳,經抓包分析重傳包都是 FIN 包,且目標 IP 已不存在。查看連接狀態發現大量 CLOSE_WAIT 狀態連接。該問題並不是一直持續,時有時無。經過對應用日誌與應用代碼分析,發現某個場景應用讀取到 EOF 時,未關閉本地 socket。進一步分析,原因是客戶端應用是 K8S 部署的,發佈後,舊實例下線,作爲客戶端發起主動關閉連接,並且舊實例的 IP 很快會被回收;服務端未關閉的 socket,在幾分鐘後 GC 時(Go 語言應用)纔會進行 socket 回收關閉操作,但此時,客戶端 IP 已不存在,因此,最後一個 FIN 報文不斷重傳,一直到超過最大重傳次數,從而問題恢復。等到再次有客戶端應用發佈時,又會出現。該問題對於沒有 GC 機制的編程語言開發的應用,可能會造成更嚴重的後果,socket 不斷泄露,導致 FD 耗盡、內存耗盡等問題。

因此,一定要警惕大量 CLOSE_WAIT 狀態連接的出現,這種情況出現時,首先要排除一些相關代碼。同時,開發過程中,一定要注意正確關閉 socket,通過一些語言特性進行兜底處理,如 Go 語言的 defer,Java 語言的 try...catch...finally,C++ 語言的 RAII 機制等。

  1. 合理設置長連接 TTL

長連接減少了像短連接頻繁建立連接的開銷,包括三次握手開銷、慢啓動開銷等。但也有一定的弊端:長連接的持續時間過長,可能會導致一些負載均衡問題,以及其他一些長時間難以收斂的問題。比如 LVS 場景,隨着後端應用實例的重啓,對於一些負載均衡算法(如輪詢),會導致最新啓動的實例連接數最少,最早啓動的實例連接數最多。對於一些客戶端負載均衡方案,當只需要連接後端集羣中的一個節點時,長連接也會出現類似的問題,比如類似 Etcd watch 的場景。有贊內部有很多使用 Etcd 的場景,早期運維每次變更 Etcd 集羣的時候都特別謹慎,避免連接的不均衡。

有贊中間件團隊規定任何應用的 TCP 長連接 TTL 不能超過 2 小時。當然,這已經是一個很保守的時長了,建議根據應用場景,合理設置 TTL。

  1. 通過域名訪問服務需定期解析 DNS

DNS 是一種服務發現機制,應用通過配置 DNS 訪問其他服務,本意是爲了解決其他服務實例 IP 變動帶來的影響,但如果處理不當還是會有問題。通過域名訪問其他服務時,需要定時更新域名解析,如果解析有更新,則需要重新建立連接,避免後端實例遷移(IP 有變化)時導致難以收斂。千萬不要只在應用啓動的時候進行一次域名解析,這種情況在 DNS 變更後想實現快速收斂,只能重啓或發佈所有相關應用了。一些語言內置了 DNS 相關的實現,需要注意對應的一些參數以及行爲是否符合預期。

另外,某些應用提供了獲取最新集羣成員列表的接口,如 Etcd、Redis,這樣即使客戶端啓動的時候只進行一次域名解析,只要定期從服務端同步服務集羣的成員列表也能支持服務端集羣成員的動態變化。

  1. 降低網絡讀寫系統調用次數

當我們調用 read/write 系統函數從 socket 讀寫數據時,每次調用都至少進行兩次用戶態與內核態的上下文切換,成本比較高。針對該問題,一般有兩種優化思路:

對於批量寫操作還有一個優點,就是可以避免 Nagle 算法帶來的延遲(一般也不建議開啓 Nagle 算法)。假如當前寫緩衝區中沒有數據,我們先通過 write 寫 4 個字節,這時 TCP 協議棧將其發送出去,然後再通過 write 寫 96 個字節,這時,由於前面發送了一個報文,還沒有收到 ACK,並且當前可發送數據未達到 MSS,Nagle 算法不允許繼續發送報文,必須等到前一個報文的 ACK 回來才能繼續發送數據,大大降低了吞吐量並且提高了延遲。如果接收端開啓了延遲 ACK,影響更大。

因此,應該儘量批量讀寫網絡數據,以提升性能。

  1. 謹慎設置 TCP 緩衝區大小

一般來說我們不需要更改 TCP 默認緩衝區大小,如果我們確實有需求設置,也需要謹慎考慮與評估。

TCP 緩衝區大小設置爲多少合適呢?我們知道,TCP 的傳輸速度,受制於發送窗口與接收窗口大小,以及網絡傳輸能力。其中,兩個窗口由緩衝區大小決定,如果緩衝區大小與網絡傳輸能力匹配,那麼緩衝區的利用率就是最高的。

帶寬時延積(縮寫爲 BDP,Bandwidth-delay Product)是用來描述網絡傳輸能力的。如最大帶寬是 100MB/s、網絡時延是 10ms 時,客戶端到服務端之間的網絡一共可以存放 100MB/s * 0.01s = 1MB 的字節,這個 1MB 是帶寬與時延的乘積,也就是帶寬時延積。這 1MB 字節存在於飛行中的 TCP 報文,它們就在網絡線路、路由器等網絡設備上。如果飛行報文超過了 1MB,就一定會讓網絡過載,最終導致丟包。

由於發送緩衝區決定了發送窗口的上限,而發送窗口又決定了已發送但未確認的飛行報文的上限,因此,發送緩衝區不能超過帶寬時延積,因爲超出的部分沒有辦法用於有效的網絡傳輸,且飛行字節大於帶寬時延積還會導致丟包,從而觸發網絡擁塞避免;而且,緩衝區也不能小於帶寬時延積,否則無法發揮出高速網絡的價值。

總結而言:緩衝區太小,會降低 TCP 吞吐量,無法高效利用網絡帶寬,導致通信延遲升高;緩衝區太大,會導致 TCP 連接內存佔用高以及受限於帶寬時延積的瓶頸,從而造成內存浪費。如果緩衝區過小,如 2K,還可能會導致快速重傳無法生效,因爲未確認的報文可能最多隻有 2 個,不會出現 3 個重複的 ACK。

Linux 系統是可以根據系統狀態自動調節緩衝區大小的,相關參數由 net.ipv4.tcp_wmem 和 net.ipv4.tcp_rmem 控制,參數是一個 3 元組 <min, default, max>,即最大值、初始默認值、最大值。但如果在 socket 上直接設置 SO_SNDBUF 或者 SO_RCVBUF,這樣會關閉緩衝區的系統動態調整功能,這樣操作前務必要進行充分的評估。因此,除非非常明確自己的需求,以及進行充分的評估與驗證,否則,不要輕易設置 TCP 緩衝區大小。

  1. 網絡相關參數支持靈活配置

當應用可能有多種部署環境、部署場景時,需要根據使用場景、網絡環境等因素,調整合適的網絡相關參數。LAN 和 WAN 的網絡狀況差別很大,會涉及到諸多參數的調整。

比如對於有讚的服務代理組件 Tether,既有數據中心內的 sidecar 部署場景,又有跨公網的網關部署場景,這時就需要按需調整對應的參數,否則難以適應不同的網絡環境。如連接超時、讀寫超時、健康檢查超時、健康檢查失敗閾值等都應該支持靈活配置。

  1. 合理設置連接池大小

對於不同類型的協議,連接池的設計也不同。我們將協議是否支持連接多路複用劃分爲兩類:非多路複用協議和多路複用協議。非多路複用協議,一個連接發送請求後,必須等待響應返回後,該連接才能發送新的請求,如 HTTP1.1、Redis 等;多路複用協議,支持同一個連接同時發送多個請求,如 HTTP2、gRPC、Dubbo 等。

我們先看一下非多路複用協議如何設置連接池大小。連接池涉及到的參數一般有:最小連接數、最大連接數、最大空閒時間、連接獲取超時時間、連接獲取超時重試次數等。應用與連接池主要交互邏輯如下所示:

我們主要討論最小連接數和最大連接數。之所以不是固定連接數,是因爲流量有高峯、有低谷;固定連接數太小,流量高峯期容易導致請求等待時間過長;固定連接數太大,流量低谷期容易造成資源浪費。因此,最小連接數對應的就是流量低谷期連接數多少爲合適,最大連接數對應的就是流量高峯期連接數多少爲合適,也就是連接數與流量大小是相關的。除了流量大小,還需要考慮請求 RT,即每個請求佔用連接的時間。所需要的連接數其實就是請求併發數,這裏我們可以利用著名的利特爾法則(Little's law)來計算,L=λW,在該場景即:併發數 = 請求 QPS * 請求 RT。比如流量低谷期請求 QPS 爲 100,請求 RT 爲 0.05s,則併發數爲 5,所需連接數爲 5;流量高峯期請求 QPS 爲 500,請求 RT 爲 0.1s,則併發數爲 50,所需連接數爲 50。這類問題其實與排隊論相關,不過我們這裏不做過多討論,如果有更復雜的需求場景,可以參考更多排隊論相關資料。

接下來我們繼續看一下多路複用協議如何設置連接池大小。連接池涉及到的參數一般有:最小連接數、最大連接數、單連接併發請求數高水位、單連接併發請求數低水位。當單連接併發請求數高於高水位時,如果連接池未達到最大連接數,進行連接池擴容,創建連接;當單連接併發請求數低於低水位時,如果連接池未達到最小連接數,進行連接池縮容,釋放連接(釋放過程需要做到平滑)。由於每個請求不獨佔連接,請求是可以選擇任意連接的,所以這裏也面臨負載均衡的問題,需要儘可能的確保每個連接上的處理中的請求數接近平均值。一般使用最少請求數負載均衡,但最少請求數負載均衡時間複雜度可能比較高,最簡單的實現需要掃描整個連接池。我們可以使用其近似的優化實現,隨機選擇兩個連接,選擇 Pending 請求數少的連接;爲了更加近似最少請求,可以選擇 3 個、5 個,甚至更多個連接,取其中 Pending 請求數最少的連接。

  1. 完善網絡指標監控

需要對各個關鍵網絡指標進行監控與告警,包括但不限於:

如果能儘早發現這些指標的異常,那麼就可以儘快發現問題,從而降低問題影響面。

總結

本文根據有贊 TCP 網絡編程實踐經驗總結了 16 項建議,希望能夠在 TCP 網絡編程方面幫助大家提升應用的健壯性、可靠性,減少線上問題與故障。

參考資料

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/5bev2XS1iX41-lY1oOF9SQ