第1章 HTTP协议基础
讲HTTP外发通道,得先聊聊HTTP本身。
很多人觉得HTTP就是调接口、发请求、收响应,没啥好学的。
但你要真想做好通道处理,协议细节就是救命稻草。我个人习惯把HTTP协议当成一本“黑话手册”——搞懂了它,服务端和客户端之间的沟通才不会有歧义。
1.1 HTTP发展史:四个里程碑
先花几分钟看看HTTP是怎么长成今天这个样子的。我刚开始做后端那会儿,还用过HTTP/1.0的老古董,想想真是泪目。
| 版本 | 发布年份 | 核心特征 |
|---|---|---|
| HTTP/0.9 | 1991 | 只有GET,没有请求头,响应只有HTML |
| HTTP/1.0 | 1996 | 加入状态码、请求头/响应头、Content-Type |
| HTTP/1.1 | 1997 | 持久连接、分块传输、缓存控制、Host头 |
| HTTP/2 | 2015 | 二进制分帧、多路复用、头部压缩、服务端推送 |
你想想看,从只能传文本到现在能跑视频、图片、实时消息,这中间的协议演进就是一部“通道效率提升史”。
个人记忆点:HTTP/1.1的持久连接是外发通道的“基础设施”。没有它,每次请求都得重建TCP连接,高并发场景下直接崩。
我曾经在一个旧项目的日志里看到大量 Connection: close,一查发现客户端还是HTTP/1.0协议——嗯,那就是通道瓶颈的罪魁祸首。
1.2 请求方法:你是来干嘛的
HTTP定义了请求方法,说白了就是告诉服务器“我想干啥”。
外发通道里最常见的就那么几个,但我发现不少新手把GET和POST混着用,出事了还一脸懵。
- GET:获取资源。幂等,安全(不修改数据)。缓存友好。
- POST:提交数据。非幂等,不安全(会改数据)。不缓存。
- PUT:替换资源。幂等,但会覆盖。
- DELETE:删除资源。幂等。
- PATCH:部分更新。非幂等。HTTP/1.1后期引入,很多框架支持得不好。
我个人习惯:查询类接口永远用GET,写操作用POST。这样你切HTTPS、做缓存、配CDN时都省心。PUT和DELETE在外发通道里用得少,但一旦用了就得注意幂等性。
1.3 状态码:服务端到底想说什么?
状态码是服务端的“表情包”。
外发通道里,你收到一个响应,先看状态码就能猜个七七八八。
我记得有次线上告警,客户端报一堆5xx,查了一圈发现是上游网关背时读超时——那状态码就是504 Gateway Timeout。
| 分类 | 范围 | 典型码 | 含义(外发通道视角) |
|---|---|---|---|
| 信息 | 1xx | 101 | 协议切换,WebSocket握手用 |
| 成功 | 2xx | 200, 201, 204 | 请求正常。204常用于通道探活 |
| 重定向 | 3xx | 301, 302, 307 | 资源移动了。外发通道要能处理Location头 |
| 客户端错误 | 4xx | 400, 401, 403, 404, 429 | 请求有问题。429是限流,通道里常见 |
| 服务端错误 | 5xx | 500, 502, 503, 504 | 服务端有问题。502/504常与网关相关 |
注意:不要把4xx当成5xx来处理。我曾经见过一个通道配置把所有非2xx都重试,结果把被限流的429又重发了十几次——嗯,直接把对方打挂了。
1.4 报文结构:协议长什么样?
你想想看,一个请求报文到底长什么样?
说白了就是三部分:起始行 → 头部 → 消息体。
请求报文示例:
POST /api/data HTTP/1.1
Host: example.com
Content-Type: application/json
User-Agent: MyChannel/1.0
Authorization: Bearer <>
{"key": "value"}
响应报文示例:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 47
Cache-Control: no-cache
{"status": "ok", "data": {"id": 123}}
核心要点:
- Content-Length:消息体长度,必须准确。外发通道里算不对长度会导致粘包或截断。
- Transfer-Encoding: chunked:流式传输,不用等完整body。实时通道很依赖这个。
- Host:
HTTP/1.1强制要求。你写代理通道时,Host头不能改错。
避坑指南:我曾经在写HTTP透传代理时,忘了把请求头里的
Host带上,结果后端一直返回400——排查了半小时才发现是Host头丢了。后来我强制在通道代码里加了个校验:如果没有Host,默认填充请求的原始地址。
报文结构看起来简单,但每个字段都可能成为通道的“坑”。
我们后面章节会反复用到这些概念,所以现在一定得把请求方法、状态码、报文结构这三块基础打扎实了。