应用层协议简介:以 HTTP 和 MQTT 为例
文章目录
- 应用层协议简介:什么是应用层协议?为什么需要应用层协议?
- 什么是应用层协议?
- 为什么需要应用层协议?
- 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:提供企业级支持。