記得剛工作那會兒,第一次接觸RPC概念時,我內心滿是疑惑——明明HTTP用得好好的,為什麼要搞出個RPC?直到參與了幾個微服務專案後,我才真正能理解它們各自的價值。今天,就讓我們一起理清這些協議之間的關係。
剛開始接觸網路編程時,我覺得TCP已經足夠完美——它能夠建立穩定的連接、保證資料可靠傳輸、處理網路擁塞,這似乎就是網路通信的全部需求。
但在實際開發中,我遇到了個基礎卻關鍵的問題:
// 發送方連續發送兩條獨立消息
socket.write("Hello");
socket.write("World");
// 接收方可能一次收到:"HelloWorld"
// 完全無法區分原始的消息邊界
這就是TCP粘包問題的典型體現。TCP基於位元組流的特性意味著它只負責可靠地傳輸位元組序列,卻不關心這些位元組應該如何被組織成有意義的業務消息。
TCP的三個核心特性:
個人理解: TCP就像是一個可靠的物流系統,保證把所有的貨物都送達,但把所有包裹混在一起投遞——貨物確實都到了,但接收方需要自己重新分類整理。
面對TCP的局限性,應用層協議應運而生。HTTP協議透過在TCP之上定義明確的報文格式,解決了消息邊界和語義表達的問題。
HTTP透過標準的報文結構定義消息邊界:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 48
{"name": "Alice", "email": "[email protected]"}
關鍵就在於Content-Length: 48
這個頭部——它明確告訴接收方消息體的確切長度,從而解決了TCP的粘包問題。
HTTP協議的主要價值:
結論: TCP解決了"可靠傳輸"的問題,而HTTP等應用層協議解決了"傳輸什麼"和"如何解析"的問題。
隨著分布式系統的發展,大家都能發現基於HTTP的服務間調用會存在一些不便:
// 基於HTTP的服務調用需要大量樣板程式碼
HttpClient client = HttpClients.createDefault();
HttpPost post = new HttpPost("http://user-service/getUser");
post.setHeader("Content-Type", "application/json");
String jsonBody = "{\"user_id\": 123}";
post.setEntity(new StringEntity(jsonBody));
HttpResponse response = client.execute(post);
if (response.getStatusLine().getStatusCode() == 200) {
String responseBody = EntityUtils.toString(response.getEntity());
User user = objectMapper.readValue(responseBody, User.class);
}
// 太多的底層細節需要處理!
每次調用都需要處理HTTP狀態碼、異常情況、序列化反序列化等重複工作。這讓我們開始思考:能否讓遠程服務調用像調用本地方法一樣簡單?
RPC(Remote Procedure Call),又叫做遠程過程調用,其目標就是讓遠程服務調用對開發者透明。
// 理想的RPC調用方式
User user = userService.getUser(123);
// 而不是處理各種網路通信細節
重要概念澄清(基於個人理解): RPC本身不是具體的協議,而是一種調用範式或技術思想。它的核心目標是讓程式設計師能夠像調用本地方法那樣調用遠程服務。
但是我們不能說“使用RPC協議”,因為RPC本身不是協議。
正確的表述方式:
因為RPC本身不是協議,而gRPC、Thrift、Dubbo等才是具體的協議實現。
RPC與HTTP的關係這是最容易產生混淆的地方。透過學習和實踐,我個人理解為:
RPC和HTTP根本不在同一個技術層級:
比如gRPC選擇基於HTTP/2協議實現,而很多早期的RPC框架使用自定義的TCP二進位協議。
協議主要定義三個核心方面:
現代RPC框架在基礎協議之上提供了企業級的能力:
總結: 協議定義了機器之間如何對話,框架讓開發者無需關心對話過程而專注業務邏輯。
透過參與實際專案,我逐漸理解了HTTP和RPC在現代架構中的分工原則。針對大部分公司而言,基本上都是如此。
在微服務架構內部,RPC框架因其性能優勢成為首選:
RPC的高性能主要源於:
高效的序列化
// JSON序列化:可讀性好但體積大
{"id": 123, "name": "Alice", "age": 30} // 約40位元組
// Protobuf二進位:體積小,解析快
\x08\x7B\x12\x05Alice\x18\x1E // 僅11位元組
// 體積減少70%以上,序列化速度提升明顯
協議開銷優化
專為性能設計
當需要向外部提供API時,HTTP協議展現出其獨特價值:
HTTP的通用性優勢:
// 前端調用HTTP API簡單直接
fetch('/api/users/123')
.then(response => response.json())
.then(user => {
displayUser(user);
});
現代互聯網公司的典型架構體現了清晰的分層設計:
這種架構的智慧:
針對文章內容,整體總結一下:
技術演進脈絡:
現代架構的最佳實踐:
核心結論: 這是一個"內外有別"的最佳實踐——性能至上的內部集群採用RPC框架,兼容性優先的對外開放介面採用HTTP協議。
本文內容是作者在學習過程中的個人理解和總結,可能存在不準確或理解有誤的地方,歡迎倔友們指正。
當然我也已經練習長達兩年半了😄,理論上🤌應該沒問題。