HTTP/HTTPS
HTTP(HyperText Transfer Protocol) 是 Web 和大量 API 通信的基础协议。HTTPS 则是在 HTTP 之下加入 TLS 加密层,用于提供身份认证、传输加密和数据完整性保护。
Abstract
HTTP/HTTPS 是理解 Web、API 网关、反向代理、负载均衡、浏览器请求和微服务入口流量的基础。
实践中需要重点关注:
- HTTP 是请求-响应模型,核心由方法、路径、Header、Body 和状态码组成
- HTTPS = HTTP + TLS,不只是“加密”,还包含服务端身份认证和完整性校验
- HTTP/1.1、HTTP/2、HTTP/3 的主要差异在连接复用、队头阻塞和传输层
- REST 是基于 HTTP 的 API 设计风格,不是新的网络协议
- 生产环境需要关注超时、缓存、代理转发、Header 透传、限流和证书管理
背景
HTTP 协议作为 Web 及现代服务通信的基础,广泛应用于页面资源加载、前后端数据交换和服务之间的调用。
HTTP 的核心抽象
- Method:表达操作语义,如
GET、POST、PUT、DELETE - URL / Path:定位资源或接口
- Header:传递元数据,如认证、内容类型、缓存策略、追踪上下文
- Body:承载请求或响应的业务数据
- Status Code:表达请求处理结果
请求与响应
HTTP 是典型的请求-响应模型。客户端发送 Request,服务端返回 Response。
sequenceDiagram
participant Client as Client
participant Server as Server
Client->>Server: HTTP Request
Server->>Server: 路由、鉴权、业务处理
Server-->>Client: HTTP Response
请求报文
一个 HTTP 请求通常包含请求行、请求头和请求体:
- 请求行:包含方法、路径和 HTTP 版本
- Header:传递请求元数据,例如目标主机、内容类型、认证信息
- Body:传递业务数据,常见于
POST、PUT、PATCH
示例
POST /api/users HTTP/1.1
Host: example.com
Content-Type: application/json
Authorization: Bearer <token>
{
"name": "Leo Yang",
"email": "leo@example.com"
}
响应报文
一个 HTTP 响应通常包含状态行、响应头和响应体:
- 状态行:包含 HTTP 版本、状态码和原因短语
- Header:传递响应元数据,例如内容类型、缓存策略、Cookie、追踪信息
- Body:返回资源数据、错误信息或页面内容
示例
HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/users/123
{
"id": "123",
"name": "Leo Yang"
}
HTTP 方法
HTTP 方法用于表达客户端希望对资源执行的操作。
| 方法 | 语义 | 是否安全 | 是否幂等 | 常见场景 |
|---|---|---|---|---|
GET |
获取资源 | 是 | 是 | 查询详情、列表 |
HEAD |
只获取响应头 | 是 | 是 | 检查资源是否存在、获取元数据 |
POST |
提交数据或触发处理 | 否 | 否 | 创建资源、提交表单、执行动作 |
PUT |
整体替换资源 | 否 | 是 | 覆盖更新 |
PATCH |
局部修改资源 | 否 | 通常否 | 修改部分字段 |
DELETE |
删除资源 | 否 | 是 | 删除对象 |
OPTIONS |
查询支持的通信选项 | 是 | 是 | CORS 预检 |
安全与幂等
- 安全(Safe):请求不应该改变服务端资源状态,例如
GET - 幂等(Idempotent):同一个请求执行多次和执行一次的最终效果相同,例如
PUT、DELETE
幂等不代表响应完全一样。例如第一次
DELETE /users/1返回204,第二次可能返回404,但资源最终都处于“已删除”状态。
状态码
HTTP 状态码用于表达请求处理结果。它只描述协议层和通用语义,具体业务错误通常还需要响应 Body 补充说明。
| 范围 | 含义 | 示例 |
|---|---|---|
1xx |
信息响应 | 100 Continue |
2xx |
成功 | 200 OK、201 Created、204 No Content |
3xx |
重定向 | 301 Moved Permanently、302 Found、304 Not Modified |
4xx |
客户端错误 | 400 Bad Request、401 Unauthorized、403 Forbidden、404 Not Found |
5xx |
服务端错误 | 500 Internal Server Error、502 Bad Gateway、503 Service Unavailable、504 Gateway Timeout |
Header
Header 用于传递请求或响应的元数据。很多 HTTP 能力都通过 Header 实现,例如内容协商、缓存、认证、跨域、追踪和代理转发。
| Header | 方向 | 作用 |
|---|---|---|
Host |
Request | 指定目标主机 |
User-Agent |
Request | 标识客户端类型 |
Accept |
Request | 声明客户端可接受的响应类型 |
Content-Type |
Request / Response | 声明 Body 的媒体类型 |
Authorization |
Request | 传递认证凭证 |
Cookie |
Request | 传递浏览器 Cookie |
Set-Cookie |
Response | 服务端设置 Cookie |
Cache-Control |
Request / Response | 控制缓存策略 |
ETag |
Response | 标识资源版本 |
If-None-Match |
Request | 配合 ETag 做协商缓存 |
Location |
Response | 指定重定向地址或新资源地址 |
X-Request-ID |
Request / Response | 请求追踪 ID |
X-Forwarded-For |
Request | 代理链路中的客户端 IP |
X-Forwarded-Proto |
Request | 原始请求协议,如 http 或 https |
代理 Header
X-Forwarded-For、X-Forwarded-Proto 等 Header 经常由反向代理或负载均衡器追加。应用不要无条件信任客户端直接传入的这些 Header,应只信任来自可信代理的转发信息。
缓存
HTTP 缓存可以减少重复请求、降低服务端压力、提升响应速度。缓存通常分为强缓存和协商缓存。
| 类型 | 机制 | 说明 |
|---|---|---|
| 强缓存 | Cache-Control: max-age=... |
缓存未过期时直接使用本地缓存,不请求服务端 |
| 协商缓存 | ETag + If-None-Match |
客户端询问服务端资源是否变化,未变化返回 304 |
| 协商缓存 | Last-Modified + If-Modified-Since |
基于资源修改时间判断是否变化 |
常见策略
- 静态资源文件名带 hash,可以设置较长缓存时间
- HTML 入口文件通常设置较短缓存或不缓存
- API 响应默认不要随意缓存,除非明确设计了缓存语义
- 用户私有数据避免被共享缓存保存
常见 Cache-Control
no-store:不允许缓存no-cache:可以缓存,但使用前必须向服务端 revalidateprivate:只允许浏览器等私有缓存保存public:允许共享缓存保存max-age=3600:缓存 3600 秒
HTTP 版本
不同 HTTP 版本的主要差异在连接使用方式、并发模型和底层传输协议。
| 版本 | 底层传输 | 特点 |
|---|---|---|
| HTTP/1.0 | TCP | 默认短连接,每次请求通常新建连接 |
| HTTP/1.1 | TCP | 默认长连接,支持管线化但实践中较少使用 |
| HTTP/2 | TCP | 二进制分帧、多路复用、Header 压缩、流控 |
| HTTP/3 | QUIC / UDP | 基于 QUIC,减少 TCP 队头阻塞,连接迁移更友好 |
队头阻塞
- HTTP/1.1 在同一连接上通常需要按顺序处理请求,容易出现应用层队头阻塞。
- HTTP/2 通过多路复用改善了这一点,但由于底层仍是 TCP,如果发生丢包,TCP 层仍可能影响同一连接上的所有流。
- HTTP/3 基于 QUIC,将多路流放到传输层,进一步降低这类影响。
HTTPS 与 TLS
HTTPS 并不是另一套应用层协议,而是给 HTTP 加上 TLS 安全层。对 HTTP/1.1 和 HTTP/2 来说,常见协议栈可以简化理解为:
HTTP = HTTP over TCP
HTTPS = HTTP over TLS over TCP
对于 HTTP/3,HTTP 运行在 QUIC 之上,QUIC 基于 UDP 并内置 TLS 1.3 握手能力。
TLS 提供三类核心能力:
- 身份认证:客户端通过证书确认服务端身份
- 传输加密:防止中间人直接读取明文内容
- 完整性校验:防止传输内容被篡改
简化后的 TLS 握手流程:
sequenceDiagram
participant Client as Client
participant Server as Server
Client->>Server: ClientHello(支持的算法、随机数)
Server-->>Client: ServerHello + Certificate(证书、公钥)
Client->>Client: 验证证书(CA链、域名、有效期)
Client->>Server: KeyShare / ClientKeyExchange(发送密钥交换参数)
Client->>Client: 生成对称密钥
Server->>Server: 生成对称密钥
Client->>Server: Finished(握手校验)
Server-->>Client: Finished(握手校验)
Client->>Server: 加密 HTTP 请求
Server-->>Client: 加密 HTTP 响应
证书校验通常包括:
- 证书是否由受信任 CA 签发
- 证书域名是否匹配访问域名
- 证书是否在有效期内
- 证书链是否完整
- 证书是否被吊销
HTTPS 常见误区
HTTPS 只能保护传输过程,不代表业务本身安全。服务端仍然需要做好认证、授权、输入校验、CSRF / XSS 防护、日志脱敏和密钥管理。
REST API
REST(Representational State Transfer)是一种基于资源的 API 设计风格,通常构建在 HTTP 之上。它关注的是如何用 HTTP 方法、URI、状态码和表示层来设计清晰、稳定的接口。
HTTP 与 REST 的关系
HTTP 是协议,REST 是接口设计风格。REST API 通常使用 HTTP,但不是所有 HTTP API 都是 REST API。
REST 的核心思路
- 用 URI 表示资源,而不是动作
- 用 HTTP 方法表达操作语义
- 用状态码表达通用处理结果
- 用 JSON 等表示层格式传递资源状态
- 服务端不依赖客户端会话状态来理解单次请求
资源命名
资源路径建议使用名词,而不是动词:
- GET:
/users - POST:
/users - GET:
/users/{id} - PATCH:
/users/{id} - DELETE:
/users/{id} - GET:
/users/{id}/orders
分页、过滤与排序
列表接口通常需要支持分页、过滤和排序:
GET /users?page=1&page_size=20&status=active&sort=-created_at
常见约定:
page/page_size:页码分页limit/offset:偏移分页cursor/limit:游标分页,适合大数据量和实时变化的数据sort=-created_at:按创建时间倒序status=active:按状态过滤
错误响应
REST API 应同时使用合适的 HTTP 状态码和结构化错误响应。
{
"code": "USER_NOT_FOUND",
"message": "user not found",
"request_id": "req_123"
}
建议:
code使用稳定的机器可读错误码message面向调用方说明错误request_id用于排障追踪- 不要在错误响应中泄露堆栈、SQL、密钥或内部服务拓扑
版本管理
常见版本管理方式:
| 方式 | 示例 | 说明 |
|---|---|---|
| URL Path | /v1/users |
简单直观,最常见 |
| Header | Accept: application/vnd.example.v1+json |
路径更干净,但调试成本稍高 |
| Query | /users?version=1 |
简单但语义较弱 |
生产实践清单
- 超时控制:客户端、网关和服务端都要设置合理超时
- 连接复用:服务端和客户端都应合理配置 keep-alive
- 请求大小:限制 request body size,避免大请求拖垮服务
- 限流保护:对用户、IP、Token 或接口维度做限流
- 缓存策略:静态资源和 API 响应使用不同缓存策略
- 安全 Header:根据场景配置 HSTS、CSP、X-Frame-Options 等
- 证书管理:监控证书有效期,自动续期,避免过期导致故障
- 日志追踪:记录方法、路径、状态码、延迟、请求大小、trace id
- 代理转发:明确可信代理范围,正确处理
X-Forwarded-* - 错误响应:状态码表达通用语义,Body 表达业务错误细节
常见排障方向
请求超时
- 检查客户端 timeout 是否过短
- 检查服务端处理耗时和下游依赖
- 检查网关、负载均衡器、应用服务器的超时配置是否一致
- 对比 P50、P95、P99 延迟,判断是否存在长尾问题
502 Bad Gateway
- 网关是否能连通上游服务
- 上游服务是否崩溃、重启或主动断开连接
- 上游响应是否不符合 HTTP 协议
- 网关和上游的 HTTP 版本、TLS 配置是否匹配
503 Service Unavailable
- 是否没有健康的上游实例
- 服务是否处于发布、维护或过载状态
- 健康检查路径是否正确
- 连接池、线程池或队列是否耗尽
504 Gateway Timeout
- 上游服务是否响应过慢
- 网关 upstream timeout 是否过短
- 服务端是否阻塞在数据库、缓存或外部 API
- 是否需要分页、异步任务或流式返回
HTTPS 证书错误
- 证书是否过期
- 访问域名是否与证书 SAN 匹配
- 证书链是否完整
- 客户端是否信任签发 CA
- 系统时间是否正确