Echo Server:压测、索引、Redis 与限流
wrk索引优化Redis限流
0. 阶段定位
这一阶段不是盲目加 Redis,而是先压测、再分析 SQL、再消除 N+1、最后对热点接口做缓存和限流。
| 项目 | 说明 |
|---|---|
| 建议位置 | 精选作品详情页 / 项目文档页 |
| 统一风格 | 左侧导航、右侧正文、表格说明、折叠代码块、阶段总结。 |
| 阅读顺序 | 建议从总览页进入,再按卡片顺序阅读。 |
1. wrk 压测脚本
用相同并发参数压测最新帖子、用户主页、帖子详情,记录吞吐和延迟。
#!/bin/bash BASE_URL="http://127.0.0.1:8080" echo "压测最新帖子列表" wrk -t4 -c100 -d30s -L "$BASE_URL/api/posts/latest?page=1&page_size=20" echo "压测用户主页" wrk -t4 -c100 -d30s -L "$BASE_URL/api/users/home?user_id=1&page=1&page_size=10" echo "压测帖子详情" wrk -t4 -c100 -d30s -L "$BASE_URL/api/posts/detail?post_id=1"
2. 索引优化
围绕 where、join、order by、group by 建索引,让列表和统计查询减少扫描。
ALTER TABLE posts ADD INDEX idx_posts_id_desc (id); ALTER TABLE posts ADD INDEX idx_posts_user_id_id (user_id, id); ALTER TABLE comments ADD INDEX idx_comments_post_id_id (post_id, id); ALTER TABLE post_likes ADD UNIQUE KEY uk_post_user (post_id, user_id); ALTER TABLE post_likes ADD INDEX idx_likes_user_id_post_id (user_id, post_id); EXPLAIN SELECT * FROM posts ORDER BY id DESC LIMIT 20;
3. N+1 查询改造
把循环查作者、点赞数、评论数的逻辑改为 JOIN + 聚合。
SELECT p.id, p.user_id, u.username, COALESCE(u.nickname, '') AS nickname, COALESCE(p.image_url, '') AS image_url, p.content, COALESCE(lc.like_count, 0) AS like_count, COALESCE(cc.comment_count, 0) AS comment_count, CASE WHEN pl_me.user_id IS NULL THEN 0 ELSE 1 END AS liked FROM posts p JOIN users u ON u.id = p.user_id LEFT JOIN post_likes pl_me ON pl_me.post_id = p.id AND pl_me.user_id = ? LEFT JOIN ( SELECT post_id, COUNT(*) AS like_count FROM post_likes GROUP BY post_id ) lc ON lc.post_id = p.id LEFT JOIN ( SELECT post_id, COUNT(*) AS comment_count FROM comments GROUP BY post_id ) cc ON cc.post_id = p.id ORDER BY p.id DESC LIMIT ? OFFSET ?;
4. Redis 缓存与限流
先缓存用户资料和帖子详情,再做热点 key 与限流,为后续点赞 Redis 化和异步落库做准备。
缓存 key 建议:
user:profile:{user_id} -> 用户资料
post:detail:{post_id} -> 帖子详情
rate:ip:{ip}:{minute} -> IP 限流计数
rate:user:{user_id}:{minute}-> 登录用户限流计数
读帖子详情流程:
1. 先 GET post:detail:{post_id}
2. 命中则直接返回
3. 未命中查 MySQL
4. SETEX post:detail:{post_id} 60 JSON
写帖子或删帖子后:
删除相关缓存,避免旧数据继续返回。