HTTP/HTTPS 网络基础
约 5356 字大约 18 分钟
HTTP/HTTPS 网络基础
HTTP基础概念 🟢
1. HTTP简介
HTTP(HyperText Transfer Protocol)是一个用于传输超媒体文档的应用层协议。它是万维网数据通信的基础,工作在客户端-服务器架构上。主要特点包括:
- 无连接
- 每次连接只处理一个请求
- 服务器处理完客户的请求,并收到客户的应答后,即断开连接
- HTTP/1.1引入了Keep-Alive机制来优化这个特点
- 无状态
- 对于事务处理没有记忆能力
- 每个请求都是独立的
- 不建立持久的连接
- 使用Cookie/Session等机制来保持状态
- 灵活
- 允许传输任意类型的数据对象
- 通过Content-Type标记数据类型
- 简单快速
- 客户向服务器请求服务时,只需传送请求方法和路径
- 常用的请求方法有GET、POST、PUT、DELETE等
2. HTTP报文结构
请求报文
请求报文由以下部分组成:
- 请求行
- 包含HTTP方法、URL、协议版本
- 示例:
GET /index.html HTTP/1.1
- 请求头
- 包含请求的附加信息
- 格式:
字段名: 值
- 常见头部:
- Host: 请求的主机名
- User-Agent: 客户端信息
- Accept: 客户端能接受的内容类型
- Cookie: 存储在客户端的数据
- Authorization: 认证信息
- 空行
- 用于分隔头部和数据部分
- 请求体
- POST等方法携带的数据
- 可以是表单数据、JSON等
示例请求报文:
GET /api/users HTTP/1.1
Host: api.example.com
User-Agent: Mozilla/5.0
Accept: application/json
Accept-Language: zh-CN,zh;q=0.9
Connection: keep-alive
Authorization: Bearer token123
响应报文
响应报文由以下部分组成:
- 状态行
- 包含协议版本、状态码、状态描述
- 示例:
HTTP/1.1 200 OK
- 响应头
- 包含服务器返回的附加信息
- 常见头部:
- Content-Type: 返回内容的类型
- Content-Length: 返回内容的长度
- Cache-Control: 缓存控制
- Set-Cookie: 设置Cookie
- Access-Control-Allow-Origin: CORS相关
空行
响应体
- 服务器返回的实际数据
- 可以是HTML、JSON、图片等
示例响应报文:
HTTP/1.1 200 OK
Date: Mon, 23 May 2023 22:38:34 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 138
Cache-Control: public, max-age=3600
Access-Control-Allow-Origin: *
{
"status": "success",
"data": {
"id": 1,
"name": "John Doe",
"email": "john@example.com"
}
}
3. HTTP方法详解
GET
- 特点
- 用于获取资源
- 请求参数包含在URL中
- 请求数据有大小限制
- 支持缓存
- 幂等性
- 使用场景
- 获取数据
- 条件查询
- 资源下载
- 示例:
GET /api/users?page=1&size=10 HTTP/1.1
Host: api.example.com
POST
- 特点
- 用于创建资源
- 参数包含在请求体中
- 参数大小无限制
- 不支持缓存
- 非幂等性
- 使用场景
- 提交表单
- 上传文件
- 创建资源
- 示例:
POST /api/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"name": "John Doe",
"email": "john@example.com"
}
PUT
- 特点
- 用于更新资源
- 幂等性
- 整体更新
- 使用场景
- 更新资源
- 上传文件到指定位置
- 示例:
PUT /api/users/1 HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"name": "John Doe Updated",
"email": "john.updated@example.com"
}
PATCH
- 特点
- 用于部分更新资源
- 非幂等性
- 局部更新
- 使用场景
- 部分字段更新
- 状态修改
- 示例:
PATCH /api/users/1 HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"name": "John Doe Updated"
}
DELETE
- 特点
- 用于删除资源
- 幂等性
- 使用场景
- 删除资源
- 软删��
- 示例:
DELETE /api/users/1 HTTP/1.1
Host: api.example.com
HEAD
- 特点
- 类似GET,但只返回头部信息
- 不返回响应体
- 用于获取资源信息
- 使用场景
- 检查资源是否存在
- 获取资源元数据
- 检查资源是否被修改
- 示例:
HEAD /api/users/1 HTTP/1.1
Host: api.example.com
OPTIONS
- 特点
- 获取目标资源支持的通信选项
- 用于CORS预检请求
- 使用场景
- CORS预检
- 获取服务器支持的方法
- 示例:
OPTIONS /api/users HTTP/1.1
Host: api.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
Origin: http://example.com
HTTP状态码 🟡
1. 1xx(信息性状态码)
表示接收的请求正在处理:
- 100 Continue
- 表示目前为止一切正常,客户端应该继续请求
- 使用场景:客户端发送带有Expect: 100-continue的请求
- 101 Switching Protocols
- 服务器根据客户端的请求切换协议
- 使用场景:WebSocket连接升级
2. 2xx(成功状态码)
表示请求正常处理完毕:
- 200 OK
- 表示请求成功
- 最常见的成功状态码
- 201 Created
- 表示资源创建成功
- POST请求的常见返回码
- 204 No Content
- 表示请求成功但无返回内容
- DELETE请求的常见返回码
- 206 Partial Content
- 表示部分内容请求成功
- 断点续传的常见返回码
3. 3xx(重定向状态码)
表示需要进行附加操作以完成请求:
- 301 Moved Permanently
- 永久重定向
- 搜索引擎会更新链接
- 302 Found
- 临时重定向
- 搜索引擎不会更新链接
- 304 Not Modified
- 资源未修改,可使用缓存
- 配合If-Modified-Since使用
- 307 Temporary Redirect
- 临时重定向
- 方法和消息主体不变
- 308 Permanent Redirect
- 永久重定向
- 方法和消息主体不变
4. 4xx(客户端错误状态码)
表示客户端发生错误:
- 400 Bad Request
- 表示请求语法错误
- 常见原因:参数错误、格式错误
- 401 Unauthorized
- 表示未授权
- 需要身份认证
- 403 Forbidden
- 表示禁止访问
- 权限不足
- 404 Not Found
- 表示资源不存在
- 最常见的错误状态码
- 405 Method Not Allowed
- 表示不允许使用该方法
- 需要查看Allow头部
- 429 Too Many Requests
- 表示请求过多
- 需要限流
5. 5xx(服务器错误状态码)
表示服务器发生错误:
- 500 Internal Server Error
- 表示服务器内部错误
- 最常见的服务器错误
- 501 Not Implemented
- 表示服务器不支持该功能
- 常见于不支持的HTTP方法
- 502 Bad Gateway
- 表示网关错误
- 服务器作为网关时无法获取响应
- 503 Service Unavailable
- 表示服务暂时不可用
- 服务器维护或过载
- 504 Gateway Timeout
- 表示网关超时
- 服务器作为网关时响应超时
HTTP Headers详解 🟡
1. 通用头部
适用于请求和响应:
- Date
- 报文创建时间
- 格式:
Date: Wed, 21 Oct 2015 07:28:00 GMT
- Connection
- 连接管理
- 值: keep-alive/close
- Cache-Control
- 缓存控制
- 常见值:
- no-cache: 强制验证缓存
- no-store: 不缓存
- max-age: 最大有效期
- public/private: 缓存访问权限
- Transfer-Encoding
- 报文主体的传输编码方式
- 常见值: chunked
示例:
Date: Mon, 23 May 2023 22:38:34 GMT
Connection: keep-alive
Cache-Control: public, max-age=3600
Transfer-Encoding: chunked
2. 请求头部
- Host
- 请求的主机名
- HTTP/1.1必需字段
- User-Agent
- 客户端信息
- 包含浏览器和操作系统信息
- Accept
- 客户端能接受的内容类型
- 多个类型用逗号分隔
- Accept-Language
- 客户端接受的语言
- 可以指定权重
- Accept-Encoding
- 客户端支持的压缩方式
- 常见值: gzip, deflate, br
- Cookie
- 客户端存储的Cookie信息
- Authorization
- 身份认证信息
- 常见格式: Bearer token
示例:
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml
Accept-Language: zh-CN,zh;q=0.9
Accept-Encoding: gzip, deflate, br
Cookie: session=123abc
Authorization: Bearer token123
3. 响应头部
- Server
- 服务器信息
- 包含服务器软件版本
- Content-Type
- 返回内容的类型
- 包含字符集信息
- Content-Length
- 返回内容的长度
- 单位为字节
- Set-Cookie
- 设置Cookie
- 可以包含多个属性:
- expires/max-age: 过期时间
- domain: 域名
- path: 路径
- secure: 仅HTTPS
- httpOnly: 禁止JS访问
- Access-Control-Allow-Origin
- CORS相关
- 允许跨域访问的域名
示例:
Server: nginx/1.18.0
Content-Type: text/html;charset=UTF-8
Content-Length: 138
Set-Cookie: session=123abc; path=/; secure; httpOnly
Access-Control-Allow-Origin: *
4. 实体头部
- Content-Type
- 实体内容的类型
- MIME类型
- Content-Length
- 实体内容的长度
- 单位为字节
- Content-Language
- 实体内容的语言
- Content-Encoding
- 实体内容的编码方式
- 常见值: gzip, deflate
- Last-Modified
- 资源最后修改时间
- 配合If-Modified-Since使用
- ETag
- 资源的唯一标识
- 配合If-None-Match使用
示例:
Content-Type: text/html;charset=UTF-8
Content-Length: 138
Content-Language: zh-CN
Content-Encoding: gzip
Last-Modified: Mon, 23 May 2023 22:38:34 GMT
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
HTTPS详解 🔴
1. HTTPS工作原理
HTTPS = HTTP + SSL/TLS,通过SSL/TLS协议提供安全性保障。
1.1 TLS握手过程
- Client Hello
- 客户端发送支持的加密套件列表
- 随机数
- 协议版本
- Server Hello
- 服务器选择加密套件
- 随机数
- 服务器证书
- 密钥交换
- 客户端验证证书
- 生成预主密钥
- 使用公钥加密发送
- 会话密钥生成
- 双方使用三个随机数生成会话密钥
- 完成握手
- 切换到加密通信
1.2 安全特性
- 加密(Encryption)
- 保护数据隐私
- 防止明文传输
- 对称加密+非对称加密
- 认证(Authentication)
- 确保服务器身份
- 防止中间人攻击
- 数字证书
- 完整性(Integrity)
- 防止内容被篡改
- 数字签名
- MAC(消息认证码)
2. SSL/TLS协议
2.1 对称加密
- 特点
- 加密解密使用相同密钥
- 计算速度快
- 密钥分发问题
- 常用算法
- AES
- DES
- 3DES
- RC4
- 示例:
// AES加密示例
const crypto = require('crypto');
function encrypt(text, key) {
const cipher = crypto.createCipher('aes-256-cbc', key);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
return encrypted;
}
2.2 非对称加密
- 特点
- 公钥加密,私钥解密
- 安全性高
- 计算速度慢
- 常用算法
- RSA
- ECC
- DSA
- 示例:
// RSA加密示例
const crypto = require('crypto');
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
});
function encrypt(text, publicKey) {
const encrypted = crypto.publicEncrypt(
publicKey,
Buffer.from(text)
);
return encrypted.toString('base64');
}
2.3 混合加密
- 工作流程
- 使用非对称加密传输对称密钥
- 使用对称密钥加密通信内容
- 优点
- 结合两种加密方式的优点
- 安全性高
- 性能好
3. 数字证书
3.1 证书内容
- 基本信息
- 版本号
- 序列号
- 签名算法
- 证书主体
- 公钥
- 主体信息
- 有效期
- 颁发者信息
- 颁发机构
- 颁发时间
- 扩展信息
- 密钥用途
- 备用名称
3.2 证书验证过程
- 验证链
- 构建证书链
- 验证每个证书的签名
- 检查信任锚
- 有效期检查
- 检查当前时间
- 检查证书有效期
- 吊销检查
- CRL(证书吊销列表)
- OCSP(在线证书状态协议)
HTTP/2特性 🔴
1. 多路复用(Multiplexing)
1.1 工作原理
- 流(Stream)
- 双向字节流
- 可以承载多个消息
- 有优先级
- 消息(Message)
- 完整的请求或响应
- 由多个帧组成
- 帧(Frame)
- 最小通信单位
- 包含帧头和载荷
1.2 优势
- 性能提升
- 解决队头阻塞
- 并行传输
- 更好的带宽利用
- 示例:
// HTTP/2客户端示例
const http2 = require('http2');
const client = http2.connect('https://example.com');
const req = client.request({
':path': '/',
':method': 'GET',
});
req.on('response', (headers) => {
// 处理响应
});
2. 服务器推送(Server Push)
2.1 工作原理
- 推送过程
- ��务器预测客户端需
- 主动推送相关资源
- 客户端缓存推送的资源
- 使用场景
- CSS文件
- JavaScript文件
- 图片资源
- 示例:
// 服务器推送示例
const http2 = require('http2');
const server = http2.createSecureServer({
key: fs.readFileSync('server.key'),
cert: fs.readFileSync('server.crt')
});
server.on('stream', (stream, headers) => {
stream.pushStream({ ':path': '/style.css' }, (err, pushStream) => {
pushStream.respondWithFile('./style.css');
});
});
3. 头部压缩(Header Compression)
3.1 HPACK算法
- 工作原理
- 静态字典
- 动态字典
- Huffman编码
- 优势
- 减少头部大小
- 提高传输效率
3.2 实现方式
- 索引编码
- 使用索引代替头部字段
- 动态更新字典
- 字面值编码
- 直接编码新的头部
- Huffman压缩
4. 二进制分帧(Binary Framing)
4.1 帧结构
- 帧头
- 长度
- 类型
- 标志
- 流标识符
- 帧载荷
- 实际数据内容
- 根据帧类型不同而不同
4.2 帧类型
- DATA
- 传输请求或响应的实体内容
- HEADERS
- 传输头部信息
- PRIORITY
- 设置流的优先级
- RST_STREAM
- 终止流
- SETTINGS
- 设置连接参数
- PUSH_PROMISE
- 服务器推送
HTTP/3特性 🔴
1. QUIC协议
1.1 特点
- 基于UDP
- 避免TCP的队头阻塞
- 灵活的拥塞控制
- 快速的连接建立
- 内置加密
- 基于TLS 1.3
- 更好的安全性
- 更快的握手
- 多路复用
- 独立的流控制
- 无队头阻塞
- 更好的并发性
1.2 优势
- 性能提升
- 减少延迟
- 提高吞吐量
- 更好的移动场景支持
- 示例:
// QUIC客户端示例
const quic = require('quic');
const client = quic.connect({
address: 'example.com',
port: 443,
// QUIC配置
});
client.on('stream', (stream) => {
// 处理流数据
});
2. 0-RTT连接建立
2.1 工原理
- 首次连接
- 完整的TLS握手
- 保存会话信息
- 后续连接
- 使用保存的会话信息
- 直接发送应用数据
2.2 安全考虑
- 重放攻击
- 服务器需要防止重放
- 使用时间戳或nonce
- 前向安全性
- 权衡安全性和性能
- 限制0-RTT数据的范围
3. 连接迁移
3.1 工作原理
- 连接标识
- 使用连接ID
- 与网络路径无关
- 迁移过程
- 检测网络变化
- 验证新路径
- 更新连接状态
3.2 应用场景
- 移动场景
- 网络切换
- IP地址变化
- 保持连接存活
- 多路径传输
- 同时使用多个网络接口
- 提高可靠性和性能
常见面试题 🔴
1. HTTP和HTTPS的区别?
1.1 安全性
- HTTP
- 明文传输
- 不安全
- 容易被监听和篡改
- HTTPS
- 加密传输
- 身份认证
- 数据完整性保护
1.2 端口
- HTTP
- 默认端口80
- 可以使用其他端口
- HTTPS
- 默认端口443
- 需要SSL证书
1.3 性能
- HTTP
- 无加密开销
- 性能较好
- HTTPS
- 有加密开销
- 需要额外的CPU和内存
- 首次连接较慢
2. HTTP/1.1相比HTTP/1.0有哪些改进?
2.1 持久连接
- 特点
- 默认开启Keep-Alive
- 复用TCP连接
- 减少握手次数
- 优势
- 提高性能
- 减少延迟
- 降低服务器负载
2.2 管道机制
- 特点
- 支持管道化请求
- 不用等待响应
- 按序返回响应
- 局限
- 队头阻塞问题
- 服务器必须按序响应
- 实际应用较少
2.3 缓存处理
- 新增缓存控制头
- Cache-Control
- ETag
- If-None-Match
- If-Modified-Since
- 缓存策略
- 强缓存
- 协商缓存
- 细粒度的控制
3. GET和POST的区别?
3.1 语义
- GET
- 获取资源
- 幂等性
- 可缓存
- POST
- 提交数据
- 非幂等性
- 一般不缓存
3.2 数据传输
- GET
- 参数在URL中
- 数据量限制
- 数据可见
- POST
- 参数在请求体中
- 数据量无限制
- 数据不可见
3.3 安全性
- GET
- 参数暴露在URL中
- 可能被记录
- 不适合敏感数据
- POST
- 参数在请求体中
- 相对更安全
- 适合敏感数据
4. HTTP的缓存机制?
4.1 强缓存
- Cache-Control
- max-age
- no-cache
- no-store
- public/private
- Expires
- 绝对时间
- HTTP/1.0遗留
- 受限于本地时间
4.2 协商缓存
- Last-Modified/If-Modified-Since
- 基于文件修改时间
- 精确到秒
- 可能存在误判
- ETag/If-None-Match
- 基于资源内容
- 更精确
- 计算成本较高
4.3 缓存位置
- Service Worker
- 离线缓存
- 可编程控制
- PWA核心技术
- Memory Cache
- 内存缓存
- 快速读取
- 时效性短
- Disk Cache
- 磁盘缓存
- 持久存储
- 容量较大
- Push Cache
- HTTP/2特性
- 会话级别
- 时效性短
示例:
// 设置缓存控制
app.get('/api/data', (req, res) => {
res.set({
'Cache-Control': 'public, max-age=3600',
'ETag': '"33a64df551425fcc55e4d42a148795d9f25f89d4"'
});
res.json({ data: 'example' });
});
// 处理协商缓存
app.get('/api/data', (req, res) => {
const etag = '"33a64df551425fcc55e4d42a148795d9f25f89d4"';
if (req.header('If-None-Match') === etag) {
res.sendStatus(304);
} else {
res.set('ETag', etag);
res.json({ data: 'example' });
}
});
HTTP安全机制 🔴
1. HTTPS详细工作流程
1.1 TLS握手过程详解(TLS 1.3)
- Client Hello
- 发送支持的TLS版本列表
- 发送支持的加密套件列表
- 发送随机数(Client Random)
- 发送PSK标识(如果有)
- 发送密钥共享扩展(包含客户端公钥)
- Server Hello
- 选择TLS版本
- 选择加密套件
- 发送随机数(Server Random)
- 发送服务器证书
- 发送服务器密钥交换参数
- 发送服务器完成消息
- 密钥计算
- 使用ECDHE算法生成预主密钥
- 结合Client Random和Server Random
- 生成主密钥
- 导出会话密钥
// TLS握手过程示例
const tls = require('tls');
const fs = require('fs');
const options = {
key: fs.readFileSync('server-key.pem'),
cert: fs.readFileSync('server-cert.pem'),
ciphers: 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384',
minVersion: 'TLSv1.3',
requestCert: true,
ca: [fs.readFileSync('client-cert.pem')]
};
const server = tls.createServer(options, (socket) => {
console.log('TLS连接已建立');
console.log('协议版本:', socket.getProtocol());
console.log('加密套件:', socket.getCipher());
console.log('会话复用:', socket.isSessionReused());
socket.on('data', (data) => {
console.log('接收加密数据:', data);
});
});
1.2 证书验证详解
- 证书链验证流程
- 构建证书链
- 验证每个证书的签名
- 检查信任锚
- 验证有效期
- 检查吊销状态
- OCSP装订
- 服务器预先获取OCSP响应
- 在TLS握手时发送
- 避免客户端单独请求
// 证书验证示例
const https = require('https');
const crypto = require('crypto');
class CertificateValidator {
static async verifyCertificate(cert) {
// 1. 验证签名
const verify = crypto.createVerify('SHA256');
verify.update(cert.raw);
const isSignatureValid = verify.verify(issuerPublicKey, cert.signature);
// 2. 验证有效期
const now = new Date();
const isDateValid = now >= cert.validFrom && now <= cert.validTo;
// 3. 验证域名
const isHostValid = cert.subject.CN === hostname;
// 4. 检查吊销状态
const isNotRevoked = await this.checkOCSP(cert);
return isSignatureValid && isDateValid && isHostValid && isNotRevoked;
}
static async checkOCSP(cert) {
const ocspReq = await this.createOCSPRequest(cert);
const ocspRes = await this.getOCSPResponse(ocspReq);
return this.verifyOCSPResponse(ocspRes);
}
}
2. HTTP/2深入解析
2.1 帧格式详解
- 帧头部结构
- Length (24 bits)
- Type (8 bits)
- Flags (8 bits)
- Stream Identifier (31 bits)
- Frame Payload
- 帧类型详解
- DATA: 传输请求或响应的实体内容
- HEADERS: 传输头部信息
- PRIORITY: 设置流的优先级
- RST_STREAM: 终止流
- SETTINGS: 设置连接参数
- PUSH_PROMISE: 服务器推送
- PING: 检测连接活跃度
- GOAWAY: 关闭连接
- WINDOW_UPDATE: 流量控制
- CONTINUATION: 继续传输头部
// HTTP/2帧处理示例
const http2 = require('http2');
class HTTP2FrameHandler {
constructor() {
this.frameTypes = {
[http2.constants.NGHTTP2_DATA]: this.handleDataFrame,
[http2.constants.NGHTTP2_HEADERS]: this.handleHeadersFrame,
[http2.constants.NGHTTP2_PRIORITY]: this.handlePriorityFrame,
[http2.constants.NGHTTP2_RST_STREAM]: this.handleRstStreamFrame,
[http2.constants.NGHTTP2_SETTINGS]: this.handleSettingsFrame,
[http2.constants.NGHTTP2_PUSH_PROMISE]: this.handlePushPromiseFrame,
[http2.constants.NGHTTP2_PING]: this.handlePingFrame,
[http2.constants.NGHTTP2_GOAWAY]: this.handleGoawayFrame,
[http2.constants.NGHTTP2_WINDOW_UPDATE]: this.handleWindowUpdateFrame,
[http2.constants.NGHTTP2_CONTINUATION]: this.handleContinuationFrame
};
}
handleFrame(frame) {
const handler = this.frameTypes[frame.type];
if (handler) {
handler.call(this, frame);
}
}
handleDataFrame(frame) {
// 处理数据帧
console.log('数据帧:', frame.data);
}
handleHeadersFrame(frame) {
// 处理头部帧
console.log('头部帧:', frame.headers);
}
}
2.2 流量控制详解
- 窗口更新机制
- 初始窗口大小
- 窗口更新帧
- 流级别控制
- 连接级别控制
- 优先级机制
- 依赖关系
- 权重分配
- 优先级调整
// 流量控制示例
const http2 = require('http2');
class FlowController {
constructor(session) {
this.session = session;
this.initialWindowSize = 65535; // 默认窗口大小
this.currentWindowSize = this.initialWindowSize;
this.session.on('stream', (stream) => {
this.handleStream(stream);
});
}
handleStream(stream) {
let consumed = 0;
stream.on('data', (chunk) => {
consumed += chunk.length;
// 当消耗了一半窗口大小时更新
if (consumed >= this.currentWindowSize / 2) {
stream.sendWindowUpdate(consumed);
this.session.sendWindowUpdate(consumed);
consumed = 0;
}
});
}
updatePriority(stream, priority) {
stream.priority({
exclusive: priority.exclusive,
parent: priority.parent,
weight: priority.weight
});
}
}
3. HTTP/3和QUIC深入解析
3.1 QUIC协议详解
- 连接建立
- 0-RTT握手
- 连接迁移
- 多路复用
- 流量控制
- 拥塞控制
- 初始窗口
- 慢启动
- 拥塞避免
- 快速恢复
// QUIC连接示例
const quic = require('quic');
class QUICConnection {
constructor(config) {
this.config = {
maxStreams: 100,
initialStreamWindowSize: 65535,
maxStreamWindowSize: 16777216,
...config
};
}
async connect(address, port) {
const connection = await quic.connect({
address,
port,
...this.config
});
this.setupConnectionHandlers(connection);
return connection;
}
setupConnectionHandlers(connection) {
connection.on('stream', (stream) => {
this.handleStream(stream);
});
connection.on('error', (error) => {
console.error('QUIC错误:', error);
});
}
handleStream(stream) {
// 实现流控制
let windowSize = this.config.initialStreamWindowSize;
stream.on('data', (data) => {
windowSize -= data.length;
if (windowSize <= this.config.initialStreamWindowSize / 2) {
stream.updateWindow(this.config.initialStreamWindowSize - windowSize);
windowSize = this.config.initialStreamWindowSize;
}
});
}
}
3.2 HTTP/3特性详解
- 流和帧
- 双向流
- 单向流
- 控制流
- 推送流
- 头部压缩
- QPACK编码
- 动态表
- 静态表
// HTTP/3服务器示例
const http3 = require('http3');
class HTTP3Server {
constructor(options) {
this.server = http3.createServer({
key: options.key,
cert: options.cert,
qpackMaxTableCapacity: 4096,
qpackBlockedStreams: 100,
maxHeaderListSize: 16384
});
this.setupServerHandlers();
}
setupServerHandlers() {
this.server.on('request', (req, res) => {
this.handleRequest(req, res);
});
this.server.on('session', (session) => {
this.handleSession(session);
});
}
handleSession(session) {
session.on('stream', (stream) => {
// 处理新的流
stream.on('headers', (headers, flags) => {
console.log('接收到头部:', headers);
});
stream.on('data', (data) => {
console.log('接收到数据:', data);
});
});
}
handleRequest(req, res) {
// 实现服务器推送
if (req.url === '/index.html') {
const pushStream = res.push('/style.css');
pushStream.end('/* CSS content */');
}
res.writeHead(200, {
'content-type': 'text/plain',
'server-timing': 'cpu;dur=2.4,memory;dur=1.2'
});
res.end('Hello HTTP/3!');
}
}
HTTP性能优化进阶 🔴
1. 缓存策略优化
1.1 多级缓存架构
- 浏览器缓存
- Memory Cache
- Disk Cache
- Service Worker Cache
- Push Cache
- CDN缓存
- Edge Cache
- Regional Cache
- Origin Cache
// 缓存策略实现
class CacheStrategy {
constructor() {
this.strategies = {
// 频繁变动的资源
api: {
cacheControl: 'no-cache',
etag: true,
vary: 'Accept-Encoding, Accept'
},
// 静态资源
static: {
cacheControl: 'public, max-age=31536000, immutable',
etag: false,
compression: true
},
// HTML文档
document: {
cacheControl: 'public, max-age=0, must-revalidate',
etag: true,
vary: 'Accept-Encoding'
}
};
}
apply(res, type) {
const strategy = this.strategies[type];
if (!strategy) return;
const headers = {
'Cache-Control': strategy.cacheControl
};
if (strategy.etag) {
headers.ETag = this.generateETag(res.body);
}
if (strategy.vary) {
headers.Vary = strategy.vary;
}
Object.entries(headers).forEach(([key, value]) => {
res.setHeader(key, value);
});
}
generateETag(content) {
const hash = crypto.createHash('sha256');
hash.update(content);
return `"${hash.digest('hex')}"`;
}
}
1.2 缓存预热和更新
- 缓存预热策略
- 定时预热
- 按需预热
- 智能预测
- 缓存更新策略
- 版本号更新
- 增量更新
- 后台更新
// 缓存预热实现
class CacheWarmer {
constructor(cache) {
this.cache = cache;
this.queue = new PriorityQueue();
}
async warmup(urls, priority = 0) {
urls.forEach(url => {
this.queue.enqueue({ url, priority });
});
await this.process();
}
async process() {
while (!this.queue.isEmpty()) {
const { url } = this.queue.dequeue();
try {
const response = await fetch(url);
const content = await response.text();
await this.cache.put(url, content);
} catch (error) {
console.error(`预热失败: ${url}`, error);
}
}
}
}
2. 压缩优化
2.1 内容协商
- 压缩算法选择
- Gzip
- Brotli
- Zstd
- 动态选择
- 压缩级别优化
- 大小与CPU的平衡
- 缓存压缩结果
- 增量压缩
// 压缩中间件
class CompressionMiddleware {
constructor(options = {}) {
this.options = {
threshold: 1024,
level: 6,
...options
};
this.algorithms = {
br: {
compress: this.brotliCompress,
priority: 1
},
gzip: {
compress: this.gzipCompress,
priority: 2
},
deflate: {
compress: this.deflateCompress,
priority: 3
}
};
}
async handle(req, res, next) {
const acceptEncoding = req.headers['accept-encoding'] || '';
const algorithm = this.selectAlgorithm(acceptEncoding);
if (!algorithm) {
return next();
}
res.body = await algorithm.compress(res.body, this.options);
res.setHeader('Content-Encoding', algorithm.name);
next();
}
selectAlgorithm(acceptEncoding) {
return Object.entries(this.algorithms)
.filter(([name]) => acceptEncoding.includes(name))
.sort(([, a], [, b]) => a.priority - b.priority)
[0];
}
}
[未完待续...]