HTTP/3与QUIC:基于UDP的零RTT连接

HTTP/2的最后问题:TCP队头阻塞 应用层多路复用 vs TCP层阻塞 HTTP/2解决了应用层队头阻塞: Stream 1: [帧1] [帧2] [帧3] Stream 2: [帧1] [帧2] [帧3] 但TCP层仍然有问题: TCP传输:[S1-帧1][S2-帧1][S1-帧2]【丢失】[S2-帧2]... ↑ TCP丢包重传,阻塞所有Stream! 即使Stream 2的数据已到达,也要等待Stream 1的丢包重传完成 QUIC协议:UDP上的可靠传输 核心思想 QUIC = UDP + TCP的可靠性 + TLS + HTTP/2多路复用 传统协议栈: 应用层 HTTP/2 安全层 TLS/SSL 传输层 TCP 网络层 IP QUIC协议栈: 应用层 HTTP/3 传输层 QUIC(在用户空间实现) 网络层 UDP 为什么选择UDP? TCP的限制: 内核实现,难以更新(Windows XP仍在用,无法升级TCP) 握手固定,无法优化 队头阻塞无法解决 UDP的优势: 没有队头阻塞 用户空间实现(QUIC协议栈在应用层) 灵活升级 QUIC核心特性 1. 0-RTT连接建立 TCP + TLS 1.2:3-RTT 客户端 → 服务器: SYN(TCP握手1) 客户端 ← 服务器: SYN-ACK(TCP握手2) 客户端 → 服务器: ACK(TCP握手3) 客户端 → 服务器: Client Hello(TLS握手1) 客户端 ← 服务器: Server Hello + Certificate(TLS握手2) 客户端 → 服务器: Finished(TLS握手3) 客户端 → 服务器: HTTP请求 总延迟:3-RTT QUIC(首次连接):1-RTT ...

2025-11-20 · maneng

HTTP/2协议:多路复用解决队头阻塞问题

HTTP/1.1的问题 队头阻塞(Head-of-Line Blocking) HTTP/1.1管道化(Pipelining): 客户端:GET /1.js → GET /2.js → GET /3.js ↓ ↓ ↓ 服务器:200 OK 等待... 等待... (1.js) 问题:第一个响应慢,阻塞后续响应 解决方案的局限 方案1:并发多个TCP连接 浏览器同时开6-8个TCP连接: 连接1: GET /1.js 连接2: GET /2.js 连接3: GET /3.js ... 问题: - TCP连接数有限 - 每个连接都要握手(延迟) - 拥塞控制独立(带宽利用率低) 方案2:域名分片 static1.example.com static2.example.com static3.example.com 每个域名6个连接 × 3个域名 = 18个连接 问题: - DNS解析开销 - TLS握手开销 - 服务器资源浪费 HTTP/2核心特性 1. 二进制分帧 HTTP/1.x:文本协议 GET /api/users HTTP/1.1\r\n Host: api.example.com\r\n \r\n HTTP/2:二进制协议 [帧头部(9字节)] +-----------------------------------------------+ | Length (24) | Type (8) | Flags (8) | Stream ID (31) | +-----------------------------------------------+ [帧负载] 帧类型: ...

2025-11-20 · maneng

HTTP协议进阶:Keep-Alive、缓存机制与内容协商

HTTP/1.0 vs HTTP/1.1 HTTP/1.0的问题 短连接(每次请求都要三次握手): 客户端 → 服务器: SYN(握手) 客户端 ← 服务器: SYN-ACK 客户端 → 服务器: ACK 客户端 → 服务器: GET /index.html 客户端 ← 服务器: HTTP/1.0 200 OK 客户端 → 服务器: FIN(挥手) 下一个请求又要重新握手! 问题: 每个请求都要建立TCP连接(+1.5 RTT延迟) 频繁握手挥手,浪费资源 服务器TIME_WAIT状态过多 HTTP/1.1的改进 1. 持久连接(Keep-Alive):默认开启 # HTTP/1.1请求 GET /api/users HTTP/1.1 Host: api.example.com Connection: keep-alive # HTTP/1.1响应 HTTP/1.1 200 OK Connection: keep-alive Keep-Alive: timeout=5, max=100 一个TCP连接,多个HTTP请求: 客户端 → 服务器: 三次握手 客户端 → 服务器: GET /api/users 客户端 ← 服务器: 200 OK 客户端 → 服务器: GET /api/orders # 复用连接 客户端 ← 服务器: 200 OK 客户端 → 服务器: GET /api/products # 复用连接 客户端 ← 服务器: 200 OK ...(5秒后无请求,关闭连接) 2. 管道化(Pipelining):不等响应,连续发送请求 ...

2025-11-20 · maneng

HTTP协议基础:请求方法、状态码与头部详解

HTTP协议概述 HTTP(HyperText Transfer Protocol):超文本传输协议 核心特点: 基于TCP(可靠传输) 无状态协议(每次请求独立) 请求-响应模式 文本协议(HTTP/1.x) HTTP请求方法 常用方法 方法 用途 是否幂等 是否安全 GET 获取资源 ✅ 是 ✅ 是 POST 创建资源/提交数据 ❌ 否 ❌ 否 PUT 更新资源(完整替换) ✅ 是 ❌ 否 PATCH 更新资源(部分修改) ❌ 否 ❌ 否 DELETE 删除资源 ✅ 是 ❌ 否 HEAD 获取响应头(不返回body) ✅ 是 ✅ 是 OPTIONS 查询支持的方法 ✅ 是 ✅ 是 幂等性:多次调用效果相同 安全性:不修改服务器状态 RESTful API设计 // 用户管理API @RestController @RequestMapping("/api/users") public class UserController { // GET /api/users - 查询所有用户 @GetMapping public List<User> listUsers() { return userService.findAll(); } // GET /api/users/123 - 查询单个用户 @GetMapping("/{id}") public User getUser(@PathVariable Long id) { return userService.findById(id); } // POST /api/users - 创建用户 @PostMapping public User createUser(@RequestBody User user) { return userService.create(user); } // PUT /api/users/123 - 完整更新用户 @PutMapping("/{id}") public User updateUser(@PathVariable Long id, @RequestBody User user) { return userService.update(id, user); } // PATCH /api/users/123 - 部分更新用户 @PatchMapping("/{id}") public User patchUser(@PathVariable Long id, @RequestBody Map<String, Object> updates) { return userService.patch(id, updates); } // DELETE /api/users/123 - 删除用户 @DeleteMapping("/{id}") public void deleteUser(@PathVariable Long id) { userService.delete(id); } } HTTP状态码 分类 类别 含义 常见状态码 1xx 信息响应 100 Continue, 101 Switching Protocols 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 重要状态码详解 200 OK HTTP/1.1 200 OK Content-Type: application/json {"id": 123, "name": "张三"} 201 Created HTTP/1.1 201 Created Location: /api/users/123 {"id": 123, "name": "张三"} 204 No Content HTTP/1.1 204 No Content # 删除成功,无返回内容 301 vs 302 301 Moved Permanently:永久重定向(浏览器会缓存) 302 Found:临时重定向(不缓存) 示例: 旧网站 http://old.com → 301 → http://new.com 304 Not Modified # 客户端请求 GET /api/users/123 If-None-Match: "abc123" # 服务器响应(资源未改变) HTTP/1.1 304 Not Modified ETag: "abc123" # 客户端使用缓存 401 vs 403 401 Unauthorized:未认证(需要登录) 403 Forbidden:已认证但无权限(权限不足) 示例: 未登录访问:401 普通用户访问管理员接口:403 502 vs 503 vs 504 502 Bad Gateway:网关从上游服务器收到无效响应 503 Service Unavailable:服务暂时不可用(维护/过载) 504 Gateway Timeout:网关超时 微服务场景: API网关 → 用户服务(宕机)→ 502 API网关 → 用户服务(超时)→ 504 用户服务主动拒绝(限流)→ 503 HTTP请求头 常用请求头 请求头 作用 示例 Host 指定服务器域名 Host: api.example.com User-Agent 客户端信息 User-Agent: Mozilla/5.0... Accept 可接受的响应类型 Accept: application/json Content-Type 请求体类型 Content-Type: application/json Authorization 认证信息 Authorization: Bearer <token> Cookie 会话Cookie Cookie: sessionId=abc123 If-None-Match 条件请求(ETag) If-None-Match: "abc123" Range 请求部分内容 Range: bytes=0-1023 微服务场景实战 // Feign客户端添加请求头 @FeignClient(name = "user-service") public interface UserClient { @GetMapping("/api/users/{id}") User getUser(@PathVariable Long id, @RequestHeader("Authorization") String token, @RequestHeader("X-Request-Id") String requestId); } // 全局请求拦截器 @Component public class FeignRequestInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate template) { // 添加链路追踪ID template.header("X-Trace-Id", MDC.get("traceId")); // 添加租户ID(多租户场景) template.header("X-Tenant-Id", TenantContext.getTenantId()); // 添加认证Token template.header("Authorization", "Bearer " + getToken()); } } HTTP响应头 常用响应头 响应头 作用 示例 Content-Type 响应体类型 Content-Type: application/json; charset=utf-8 Content-Length 响应体长度 Content-Length: 1234 Cache-Control 缓存策略 Cache-Control: max-age=3600 ETag 资源版本标识 ETag: "abc123" Location 重定向地址 Location: /api/users/123 Set-Cookie 设置Cookie Set-Cookie: sessionId=abc; HttpOnly Access-Control-Allow-Origin CORS跨域 Access-Control-Allow-Origin: * Spring Boot响应头配置 // 方式1:在Controller中设置 @GetMapping("/api/users/{id}") public ResponseEntity<User> getUser(@PathVariable Long id) { User user = userService.findById(id); return ResponseEntity.ok() .header("X-Custom-Header", "custom-value") .eTag("\"" + user.getVersion() + "\"") // ETag .cacheControl(CacheControl.maxAge(1, TimeUnit.HOURS)) // 缓存1小时 .body(user); } // 方式2:全局响应拦截器 @Component public class ResponseHeaderInterceptor implements HandlerInterceptor { @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { // 添加安全响应头 response.setHeader("X-Content-Type-Options", "nosniff"); response.setHeader("X-Frame-Options", "DENY"); response.setHeader("X-XSS-Protection", "1; mode=block"); } } Cookie与Session Cookie工作原理 [首次请求] 客户端 → 服务器: GET /login 服务器 → 客户端: Set-Cookie: sessionId=abc123; Path=/; HttpOnly [后续请求] 客户端 → 服务器: GET /api/users Cookie: sessionId=abc123 服务器根据sessionId识别用户 Cookie属性 属性 作用 示例 Expires 过期时间(绝对时间) Expires=Wed, 21 Oct 2025 07:28:00 GMT Max-Age 有效期(秒) Max-Age=3600 Domain 作用域 Domain=.example.com Path 路径 Path=/api Secure 仅HTTPS Secure HttpOnly 禁止JavaScript访问 HttpOnly SameSite 防止CSRF SameSite=Strict Session管理(微服务) 问题:微服务场景Session共享 ...

2025-11-20 · maneng

如约数科科技工作室

浙ICP备2025203501号

👀 本站总访问量 ...| 👤 访客数 ...| 📅 今日访问 ...