文章目錄
- 應用層協議簡介:什么是應用層協議?為什么需要應用層協議?
- 什么是應用層協議?
- 為什么需要應用層協議?
- HTTP 協議詳解
- HTTP 協議特點
- HTTP 工作的基本原理
- HTTP 請求與響應示例
- 為什么 Web 應用基于 HTTP 請求?
- HTTP 的版本演進
- HTTP 的典型應用場景
- 拓展:RPC
- 為什么說 RPC 屬于應用層協議?
- RPC 與 HTTP 的優缺點分析
- RPC 的優缺點
- HTTP(RESTful API)的優缺點
- 技術選型建議
- MQTT 協議詳解
- MQTT 核心特性
- MQTT 協議架構
- 關鍵概念
- 主題 Topic
- QoS 等級
- 保留消息(Retained Message)
- 會話持久性
- MQTT 與 HTTP 對比
- 常見的 MQTT Broker 實現
應用層協議簡介:什么是應用層協議?為什么需要應用層協議?
什么是應用層協議?
應用層協議是網絡通信中面向具體應用場景的規則集合,定義了數據格式、交互流程和功能邏輯。
它位于 OSI 網絡模型的最頂層,直接服務于應用程序。「這一點我個人認為很關鍵,應用層協議是直接服務于應用程序的,比如基于 HTTP 協議可以高效地構建 web 服務」
典型的協議包括:HTTP(網頁)、SMTP(郵件)、DNS(域名解析)、FTP(文件傳輸)等。
核心作用:
- 結構化數據:規定數據應該如何組織(如 HTTP 報文包含請求行、頭部、正文);
- 語義約定:定義交互邏輯(HTTP 中
GET
獲取資源,POST
提交數據); - 狀態管理:處理會話(如 Cookies 維持登錄狀態)。
為什么需要應用層協議?
我們已經知道,基于 TCP 協議或 UDP 協議可以完成端到端的字節流或數據包的傳輸。以 TCP 協議為例,TCP 可以可靠地在客戶端與服務端之間傳輸字節流,但是傳輸的僅僅是字節流,如果不加以解析,這些字節流不具備具體的含義。
我們當然可以根據具體的業務來在 TCP 傳輸的字節流當中手動地加入一些代表語義的信息,與字節流一同發送,但這樣做的一個很明顯的問題在于復用性非常差,具體的業務與傳輸無法解耦。
基于上述分析,應用層協議應運而生,基于應用層協議,數據被賦予了具體的意義。以 HTTP 協議為例,它更多地提供的是一種標準,比如 GET
請求的 HTTP 報文明確要求從服務器請求資源,所有遵循 HTTP 協議的服務都能理解這個語義,而不需要額外協商。
下面看一個使用和不使用應用層協議進行數據傳輸的例子:
如果不使用應用層協議,客戶端基于傳輸層協議發送原始字節流:48 54 54 50
,服務器無法判斷出這個字節流要做的是什么,需要額外的代碼進行解析。
而如果使用應用層協議,客戶端將發送結構化的請求數據:
GET /index.html HTTP/1.1
Host: yggp.test
Accept-Language: en
服務器將在應用層按照 HTTP 協議的規則對發送過來的報文進行解析,具體需要解析 HTTP 請求的類型、解析路徑并返回對應頁面。
總結一下,應用層協議為具體的業務邏輯與網絡傳輸搭起了橋梁,將原始的字節流升級為可理解的業務操作。沒有應用層協議,互聯網將陷入混亂的自定義格式沖突(比如 A 公司將 TCP 報文的第一位為1
視為請求數據,B 公司視為刪除數據,存在沖突,需要額外的協商成本),無法實現跨平臺、跨系統的寫作。
HTTP 協議詳解
HTTP(HyperText Transfer Protocol, 超文本傳輸協議)是互聯網上應用最廣泛的應用層協議,用于在客戶端(如瀏覽器)和服務器之間傳輸超文本(如網頁、API 數據等)。它是 Web 應用的基礎通信協議,幾乎所有現代 Web 應用都依賴 HTTP 進行數據交互。
HTTP 協議特點
HTTP 協議的核心作用是在客戶端和服務器之間傳輸超文本,主要特點包括:
- 使用請求-響應(Request-Response)模型:客戶端發送請求(Request,請求報文需要攜帶相應的方法),服務器返回響應(Response,通常是一個 JSON 結構體);
- 無狀態協議:HTTP 協議默認不記錄用戶的狀態(但是可以通過 Cookie/Session 實現狀態管理,可以將 JWT Access Token 放到 HTTP Header 當中,由服務端進行無狀態認證);
- 支持多種數據格式:包括 HTML、JSON、XML、圖片、視頻等;
- 可拓展性強:通過 HTTP Header 可以傳遞額外信息(如認證、緩存控制等)。
HTTP 工作的基本原理
HTTP 工作的基本流程如下:
- 用戶在瀏覽器輸入 URL 并按下回車(客戶端發起請求);
- DNS 解析(DNS 也是應用層協議,主要用于將 URL 對應到具體的 IP 地址,需要注意的是,一個 URL 可能對應多個 IP,因為可能不止一臺服務器在提供服務);
- 得到 IP 之后與服務器建立 TCP 連接(比如基于 TCP 傳輸的 HTTP,默認的端口號是 80,HTTPS 默認的端口號是 HTTPS,基于端口號和 IP 在客戶端與服務器之間建立 Socket 連接);
- 連接建立之后,客戶端發送 HTTP 請求(比如
GET /index.html HTTP/1.1
); - 服務器處理請求(查找資源,執行后端邏輯);
- 服務器返回 HTTP 響應(如
200 OK
+ HTML 的內容); - 客戶端得到 HTML 內容后,對文本進行解析并在客戶端瀏覽器進行渲染。
HTTP 請求與響應示例
HTTP 請求(Request)
# GET 請求
GET /index.html HTTP/1.1 // 請求行
Host: www.example.com // 必需頭部
User-Agent: Mozilla/5.0 // 客戶端信息
Accept: text/html // 期望返回的格式# POST 請求
POST /api/login HTTP/1.1 // 請求行
Host: example.com // 必需頭部
Content-Type: application/json // 指定 Body 格式
Content-Length: 56 // Body 的長度(字節)
User-Agent: Mozilla/5.0 // 客戶端信息
Accept: application/json // 期望返回的格式{"username": "admin", "password": "123456"} // 請求體(Body)
- 方法:GET 用于獲取資源,POST 會提交數據,PUT 更新數據,DELETE 刪除數據。因此為了確保接口的冪等性,應該重點關注 POST 和 PUT 等改變服務器狀態的方法會不會在重復提交請求之后多次改變服務器中資源的狀態。
- 路徑:
/index.html
是請求的資源。 - 協議版本:
HTTP/1.1
標識了協議版本。 - Headers:附加信息。
HTTP 響應(Response)
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1234<!DOCTYPE html>
<html>...</html>
- 狀態碼(Status Code):比如 200 表示請求成功,404 表示資源未找到。
- Headers:描述數據(Content-Type、Content-Length);
- Body:返回實際的數據(HTML、JSON)。
為什么 Web 應用基于 HTTP 請求?
- 簡單且標準化:HTTP 采用純文本協議,易于調試和拓展,但問題在于需要考慮安全性,所以當前瀏覽器默認只能夠以 HTTPS 協議發起請求,否則就會告知用戶不安全。此外,HTTP 采用請求-響應模型,適合 Web 交互。
- 跨平臺兼容:幾乎所有設備(PC、手機、IoT「后面要提到的 MQTT 更適用于 IoT」)都支持 HTTP。此外,瀏覽器、移動 APP 和后端應用都可以通過 HTTP 通信。
- 無狀態但可拓展:HTTP 協議默認不保存狀態(但可拓展到 HTTP Header 保存登錄態),因此適用于分布式系統。
- 支持多種數據格式:早期用于 HTML,現在廣泛用于 RESTful API(JSON)、文件傳輸、流媒體等。
- 與 HTTPS 結合保證安全:HTTPS = HTTP + SSL/TLS,加密傳輸防止竊聽和數據篡改(比如銀行交易)。
- 支持緩存和優化:通過
Cache-Control
、ETag
等頭部優化性能,減少服務器負載。
HTTP 的版本演進
目前 HTTP 已經演化到了第三代,HTTP/3 采用的傳輸層協議也不再是 TCP,而是 UDP。甚至 HTTP/2 不再采用字節流的形式傳輸文本,而采用二進制協議來傳輸數據,以提升傳輸效率,gRPC 框架在發起調用時正是通過 HTTP/2 進行數據傳輸。
HTTP 的版本演進詳見下表:
版本 | 特點 |
---|---|
HTTP/1.0 | 基于最簡單的請求-響應模型,但不存在連接復用,意味著每一次發起 HTTP 請求都需要新建 TCP 連接(效率低) |
HTTP/1.1 | 持久連接(Keep-Alive)、管道化、緩存優化。HTTP/1.1 是目前廣泛使用的主流版本 |
HTTP/2 | 二進制協議、多路復用(一個連接并行多個請求)、頭部壓縮 |
HTTP/3 | 基于 QUIC(UDP),解決 TCP 對頭阻塞,提升移動網絡下的性能 |
HTTP 的典型應用場景
- 網頁瀏覽(瀏覽器從服務器請求網頁資源,用戶還可以在瀏覽器向服務器提交表單);
- RESTful API(前端與后端進行數據交互);
- 文件下載/上傳(HTTP 替代了部分 FTP 協議的功能);
- 實時通信(結合 WebSocket,實現即時通訊);
- 微服務通信(服務間通過 HTTP API 交互,gRPC 是一個典型的例子)。
拓展:RPC
近期時興的后端開發技術中,最繞不開的一項技術一定包括微服務,微服務當中涉及到 RPC,也就是遠程過程調用,它能夠讓客戶端像是在調用本地函數一樣來調用一個遠程服務器上的業務函數。
根據以上概念,RPC 其實可以被歸納為應用層協議的一種,因為它屏蔽了底層網絡傳輸的細節,更恰當地來說它應該被視為一種通信模式。實際上,RPC 是一個更上層的通信范式,它可以基于不同的底層協議(如 gRPC 基于 HTTP/2 協議通信,Dubbo 基于 TCP 協議通信,RPC 還可以基于自定義的協議來進行通信)實現。
為什么說 RPC 屬于應用層協議?
RPC 的功能特性
- 接口抽象:RPC 定義了遠程服務的函數,客戶端與服務器建立連接后可以直接通過客戶端對象進行調用(如
getUser(id)
); - 序列化:RPC 需要將數據轉換為網絡可傳輸的格式,比如 JSON 或 Protobuf,具體來說是將 RPC 調用的參數轉為網絡可傳輸格式,服務端接收到字節流之后再將字節流反序列化為參數;
- 服務發現:客戶端需要通過服務發現來定位目標服務器,服務發現的功能類似于 DNS;
- 負載均衡:比如客戶端根據服務發現模塊拉取的服務實例列表,根據調度策略隨機選擇一個服務實例執行 RPC 調用,實現負載均衡。
協議對比:RPC vs. HTTP
特性 | RPC | HTTP |
---|---|---|
目標 | 調用遠程函數 | 通過標準方法(GET/POST)獲取資源 |
通信模式 | 函數調用導向 | 資源導向 |
協議綁定 | 可基于 TCP、HTTP、自定義協議 | 必需基于 HTTP/HTTPS |
性能優化 | 高效序列化(如基于 protobuf 的二進制序列化) | 基于文本協議(JSON/XML) |
性能 | 更高(低延遲、高吞吐) | 較低(文本傳輸和解析的開銷較大) |
適用場景 | 微服務內部通信、高性能場景 | 對外開放 API、瀏覽器兼容場景 |
RPC 與 HTTP 的優缺點分析
RPC 的優缺點
?優點
- 高性能:可以使用二進制協議(比如 gRPC 使用 Protobuf)進行通信,數據體積小,序列化/反序列化快。支持多路復用(HTTP/2)或長連接(比如 Dubbo 基于 TCP 協議通信),減少 TCP 建立連接的握手開銷;
- 開發友好:遠程過程調用就像是調用本地函數一樣簡單,隱藏了網絡的實現細節。此外,以 gRPC 為例,編寫好 proto 文件之后可以直接根據 proto 文件生成相應開發環境(比如 C++/Python/Golang)的業務結構及接口,即自動生成客戶端代碼。
?缺點
- 耦合性高:客戶端和服務端共享接口定義文件(即 proto 文件),如有變更需要同步更新。
- 調試復雜:二進制協議難以直接閱讀,需要工具解析。此外,需要專門的監控工具來對調用鏈進行監控,以防服務雪崩的發生。
- 穿透性差:基于自定義通信協議或 TCP 協議的 RPC 可能被防火墻攔截,但基于 HTTP 通信的 RPC 可以通過。
HTTP(RESTful API)的優缺點
?優點
- 通用性強:所有設備均支持 HTTP,無需額外的庫。且基于 HTTP 協議傳輸的數據是純文本,人類可讀,便于調試。
- 無狀態:符合 REST 規范,易于水平拓展。
- 穿透性好:默認使用 80/443 端口,輕松穿透防火墻與代理。
- 生態豐富:HTTP 具有豐富的工具鏈(Swagger 文檔、CDN 緩存、OAuth 認證等)。
?缺點
- 性能較低:基于純文本協議傳輸,傳輸開銷較大,解析較慢,不適用于高頻調用。
- 靈活性差:由于 HTTP 協議通過具體的方法進行調用,目的是請求資源,因此與 CRUD 強綁定,復雜操作需要繞行。
- 冗余性高:頭部信息重復傳輸(比如一個 HTTP 請求如果需要無狀態認證,需要多次傳輸相同的 JWT Access Token),浪費帶寬。
技術選型建議
- 對內使用 RPC,對外使用 HTTP。
- 追求性能時使用二進制協議(Protobuf),追求通用性時選 JSON over HTTP。
MQTT 協議詳解
MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸)是一種輕量級的發布/訂閱(Pub-Sub)消息協議,專為低帶寬、高延遲或不穩定網絡環境設計。
需要注意的是,MQTT 是典型的應用層協議,它明確基于 TCP/IP 協議棧進行通信,專為物聯網(IoT)和低帶寬環境設計。
MQTT 核心特性
MQTT 的核心特性如下:
- 輕量級:協議頭僅 2 字節(16 位),適合嵌入式設備(如傳感器);
- 發布/訂閱模型:解耦消息生產者(Publisher)和消費者(Subscriber),通過主題(Topic)路由消息「和 Message Queue 的設計理念基本一致」;
- 低功耗:適合電池供電設備(如智能家居傳感器);
- 支持 QoS 等級:提供 3 種消息傳遞可靠性保證等級(QoS 0/1/2);
- 基于 TCP/IP:默認端口 1883,8883 為 TLS 加密端口;
- 遺囑消息(LWT):設備異常離線時,自動向訂閱者發送預設消息。
MQTT 協議架構
核心角色
主要分為三部分,分別是發布者(Publisher)、訂閱者(Subscriber)和代理服務器(Broker),與 MQ 的設計方式基本相同。
- Publisher:向特定 Topic 發送消息的設備;
- Subscriber:訂閱 Topic 并接收消息的設備;
- Broker:負責消息路由的核心組件(如 Mosquitto、EMQX)。
通信流程
- 設備(客戶端)連接到 MQTT Broker;
- 訂閱者訂閱感興趣的主題(如
sensor/temperature
); - 發布者向該主題發布消息(如
{"avlue": 25.5}
); - Broker 將消息推送給所有訂閱者。
關鍵概念
主題 Topic
- 主題采用多級結構,用
/
分隔,如home/living_room/temperature
; - 主題支持通配符:
+
為單機匹配,比如home/+/temperature
匹配home/living_room/temperature
;#
為多級匹配,如home/#
匹配home/living_room/temperature
和home/kitchen/temperature
。
QoS 等級
QoS | 可靠性 | 傳輸次數 | 用例 |
---|---|---|---|
0 | 最多一次(可能丟失) | 1 1 1 | 非關鍵數據(如周期性傳感器讀數) |
1 | 至少一次(可能重復) | ≥ 1 \geq1 ≥1 | 需保證送達(如設備控制指令) |
2 | 恰好一次(可靠且不重復) | ≥ 2 \geq2 ≥2 | 嚴格場景(如支付交易) |
保留消息(Retained Message)
Broker 保留主題的最后一條消息,新的訂閱者立即收到它(如設備上線后獲取最新狀態)。
會話持久性
客戶端設置 Clean Session = false
之后,Broker 會保存離線期間的訂閱和未接收消息。
MQTT 與 HTTP 對比
對比維度 | MQTT | HTTP |
---|---|---|
設計目標 | 設備間實時消息推送 | 基于請求-響應模型的資源傳輸 |
傳輸開銷 | 極小 | 高(Headers + Body,且基于純文本傳輸) |
連接方向 | 設備可主動發布消息 | 只能客戶端發送請求 |
適用場景 | IoT、即時通訊 | Web API、網頁資源加載 |
長連接 | 保持 TCP 長連接 | 短連接(HTTP/1.1 可連接復用) |
常見的 MQTT Broker 實現
- Mosquitto:Eclipse 開源項目,輕量級 Broker;
- EMQX:高性能 MQTT Broker,支持集群;
- AWS IoT Core:云服務集成;
- HiveMQ:提供企業級支持。