# livePing(爱生活点评)-高并发项目 **Repository Path**: recursiveSoup/livePing ## Basic Information - **Project Name**: livePing(爱生活点评)-高并发项目 - **Description**: 这是一个优秀的高并发场景解决方案项目,核心亮点为缓存三兄弟的处理,高并发秒杀场景下防止超卖,消息队列削峰填谷异步下单提升接口响应速度,死信队列兜底。 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: dev_01 - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-11-13 - **Last Updated**: 2026-06-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 爱生活点评 - 高并发社区点评系统后端 > 基于 Spring Boot 3.2.5 + Redis + RabbitMQ + Redisson 构建的高并发社区点评系统 --- ## 项目简介 爱生活点评是一个仿大众点评的社区点评系统后端,实现了用户认证、商铺管理、优惠券秒杀、探店笔记、关注社交等核心功能。项目重点解决了高并发场景下的缓存穿透/击穿/雪崩、秒杀超卖、分布式锁等技术难题。 --- ## 技术栈 | 层级 | 技术 | 版本 | |------|------|------| | 框架 | Spring Boot | 3.2.5 | | ORM | MyBatis-Plus | 3.5.5 | | 缓存 | Redis + Redisson | 3.27.0 | | 消息队列 | RabbitMQ | Spring AMQP | | 数据库 | MySQL | 8.0.33 | | 对象存储 | 阿里云 OSS | 3.17.4 | | 工具库 | Hutool | 5.8.27 | | JDK | Java | 17 | --- ## 项目结构 ``` src/main/java ├── com.hmdp │ ├── config/ # 配置类 │ │ ├── BloomFilterConfig.java # 布隆过滤器配置 │ │ ├── CacheWarmUpRunner.java # 启动缓存预热 │ │ ├── MvcConfg.java # MVC 拦截器配置 │ │ ├── MybatisConfig.java # MyBatis-Plus 配置 │ │ ├── RabbitMQConfig.java # RabbitMQ 队列/交换机 │ │ ├── RedissonConfig.java # Redisson 配置 │ │ ├── ScheduleConfig.java # 定时任务配置 │ │ ├── ThreadPoolConfig.java # 线程池配置 │ │ └── WebExceptionAdvice.java # 全局异常处理 │ ├── controller/ # 控制器层(9个) │ ├── dto/ # 数据传输对象 │ ├── entity/ # 实体类(10个) │ ├── mapper/ # MyBatis Mapper(10个) │ ├── mq/ # RabbitMQ 消费者 │ │ ├── SeckillOrderConsumer.java # 秒杀订单消费者 │ │ └── DLXConsumer.java # 死信队列消费者 │ ├── properties/ # 配置属性类 │ ├── schedule/ # 定时任务 │ │ └── StockReconciliationTask.java # 库存对账任务 │ ├── service/ # 服务接口 + 实现 │ └── utils/ # 工具类 │ ├── AliOssUtil.java # 阿里云 OSS 工具 │ ├── CacheClient.java # 缓存工具类(通用) │ ├── RedisIdWorker.java # 分布式 ID 生成器 │ ├── SimpleRedisLock.java # 分布式锁实现 │ └── ... ├── constant/ # 常量类(6个) └── HmDianPingApplication.java src/main/resources ├── application.yaml # 配置文件 ├── script/ # Lua 脚本 │ ├── seckill.lua # 秒杀资格校验 │ ├── likeBlog.lua # 点赞/取消点赞 │ └── unlock.lua # 分布式锁安全释放 ├── mapper/ # MyBatis XML 映射 └── db/ # 数据库脚本 ``` --- ## 核心功能模块 ### 1. 用户模块 - **手机号验证码登录**:Redis 存储验证码(TTL 2分钟),登录后生成 UUID token 存入 Redis Hash - **双层拦截器认证**: - `RefreshTokenInterceptor`(全局):从请求头提取 token,恢复用户信息到 ThreadLocal - `LoginInterceptor`(需登录接口):检查 ThreadLocal 中是否有用户 - **用户签到**:Redis Bitmap 实现,`BITFIELD` 命令统计连续签到天数 ### 2. 商铺模块 - **多级缓存防护**: - 布隆过滤器拦截不存在的商铺 ID(100万元素,0.01% 误判率) - 逻辑过期 + 互斥锁解决缓存击穿 - 空对象缓存解决缓存穿透 - **地理位置查询**:Redis GEO 存储商铺坐标,`GEORADIUS` 实现按距离排序分页 ### 3. 秒杀优惠券模块 - **Lua 脚本原子校验**:库存判断 + 用户去重 + 库存扣减,一步完成 - **RabbitMQ 异步下单**:校验通过后立即返回订单 ID,消息队列异步写入数据库 - **乐观锁扣减库存**:`UPDATE SET stock=stock-1 WHERE stock>0` - **死信队列兜底**:消费失败的消息进入死信队列,记录日志 - **库存预热 + 定时对账**:启动时加载库存到 Redis,每5分钟对账一次 ### 4. 博客/探店笔记模块 - **Feed 流推模式**:发布笔记时推送到粉丝 Redis ZSet 收件箱 - **滚动分页查询**:`ZREVRANGEBYSCORE` 按时间戳倒序分页 - **点赞防重**:Lua 脚本实现原子化点赞/取消点赞(ZSet 天然去重) - **点赞排行榜**:`ZRANGE 0 9` 取 Top10 点赞用户 ### 5. 关注模块 - **关注/取关**:MySQL 持久化 + Redis Set 双写 - **是否关注判断**:`SISMEMBER` O(1) 查询 - **共同关注**:`SINTER` 取两个用户关注集合的交集 ### 6. 文件上传模块 - **本地上传**:UUID + 哈希分目录存储 - **阿里云 OSS 上传**:按年/月生成目录结构,10MB 文件大小限制 --- ## 项目亮点 1. **高并发秒杀架构**:Lua 脚本原子校验 + RabbitMQ 异步下单 + 乐观锁扣减 + 死信队列兜底 + 定时对账 2. **多级缓存防护体系**:布隆过滤器 → 逻辑过期 + 互斥锁 → 空对象缓存 3. **通用缓存工具类**:泛型 + 函数式编程封装缓存策略,一套代码复用全业务 4. **Feed 流推模式**:发布即推送到粉丝 ZSet 收件箱,高效滚动分页 5. **分布式 ID 生成器**:Redis INCR + 位运算实现高性能全局唯一 ID 6. **Redis 全数据结构实战**:String/Hash/Set/ZSet/Bitmap/GEO/布隆过滤器,覆盖7种数据结构 7. **Lua 脚本原子化**:3个 Lua 脚本解决秒杀校验、点赞防重、锁安全释放 8. **优雅的用户认证**:双拦截器 + ThreadLocal + Redis Token 实现无状态登录 9. **完善的线程池隔离**:3个独立线程池分别处理秒杀订单、缓存重建、定时任务 --- ## Redis 数据结构使用 | 数据结构 | 业务场景 | Key 格式 | |---------|---------|---------| | String | 验证码、缓存、库存、分布式锁 | `login:code:{phone}`, `cache:shop:{id}`, `seckill:stock:{id}` | | Hash | 用户登录态 | `login:token:{token}` | | Set | 关注列表、秒杀下单用户 | `follow:{userId}`, `seckill:order:{voucherId}` | | ZSet | 点赞列表、Feed 流收件箱 | `blog:liked:{blogId}`, `feed:{userId}` | | Bitmap | 用户签到 | `sign:yyyy:MM:{userId}` | | GEO | 商铺坐标 | `shop:geo:{typeId}` | | 布隆过滤器 | 商铺 ID 防穿透 | `bloom:shop` | --- ## Lua 脚本 | 脚本 | 用途 | |------|------| | `seckill.lua` | 秒杀资格校验(库存 + 用户去重 + 扣减) | | `likeBlog.lua` | 点赞/取消点赞原子操作 | | `unlock.lua` | 分布式锁安全释放 | --- ## API 接口 ### 用户相关 - `POST /user/code` - 发送验证码 - `POST /user/login` - 用户登录 - `POST /user/logout` - 用户登出 - `GET /user/me` - 获取当前用户信息 - `POST /user/sign` - 用户签到 - `GET /user/sign/count` - 获取连续签到天数 ### 商铺相关 - `GET /shop/{id}` - 查询商铺详情 - `POST /shop` - 新增商铺 - `PUT /shop` - 更新商铺 - `GET /shop/of/type` - 按类型分页查询商铺 - `GET /shop/of/name` - 按名称搜索商铺 ### 优惠券相关 - `POST /voucher` - 新增普通优惠券 - `POST /voucher/seckill` - 新增秒杀优惠券 - `GET /voucher/list/{shopId}` - 查询商铺优惠券列表 - `POST /voucher-order/seckill/{id}` - 秒杀抢购 ### 博客相关 - `POST /blog` - 发布探店笔记 - `GET /blog/{id}` - 查询笔记详情 - `GET /blog/hot` - 查询热门笔记 - `PUT /blog/like/{id}` - 点赞/取消点赞 - `GET /blog/likes/{id}` - 查询点赞用户列表 - `GET /blog/of/me` - 查询我的笔记 - `GET /blog/of/follow` - 查询关注的人的笔记 ### 关注相关 - `PUT /follow/{id}/{isFollow}` - 关注/取关 - `GET /follow/or/not/{id}` - 查询是否关注 - `GET /follow/common/{id}` - 查询共同关注 ### 文件上传 - `POST /upload/blog` - 上传图片 --- ## 环境要求 - JDK 17+ - MySQL 8.0+ - Redis 6.0+ - RabbitMQ 3.0+ - Maven 3.6+ ## 快速启动 ```bash # 1. 克隆项目 git clone # 2. 创建数据库 mysql -u root -p -e "CREATE DATABASE dp002 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;" # 3. 导入数据库脚本 # 脚本位置:src/main/resources/db/hmdp.sql # 包含表:tb_user, tb_shop, tb_shop_type, tb_blog, tb_follow, tb_seckill_voucher, tb_sign 等 # 已包含测试数据(用户、商铺、商铺类型等) mysql -u root -p dp002 < src/main/resources/db/hmdp.sql # 4. 修改配置 # 修改 application.yaml 中的数据库连接信息、Redis、RabbitMQ 配置 # 5. 启动 Redis 和 RabbitMQ # 6. 运行项目 mvn spring-boot:run ``` --- ## 配置说明 ### 数据库配置 ```yaml spring: datasource: url: jdbc:mysql://127.0.0.1:3306/dp002?useSSL=false&serverTimezone=UTC username: root password: 123456 ``` ### Redis 配置 ```yaml spring: data: redis: host: localhost port: 6379 database: 1 ``` ### RabbitMQ 配置 ```yaml spring: rabbitmq: host: localhost port: 5672 username: admin password: admin virtual-host: /livePing ``` --- ## 线程池配置 | 线程池 | 核心/最大线程 | 队列容量 | 用途 | |--------|-------------|---------|------| | `seckillOrderExecutor` | 2/4 | 500 | 秒杀订单异步处理 | | `cacheRebuildExecutor` | 5/10 | 200 | 缓存异步重建 | | `scheduledTaskExecutor` | 2/4 | 100 | 定时任务执行 | --- ## 部署架构 ### 前后端分离部署 ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ 浏览器 │────▶│ Nginx │────▶│ Spring Boot │ │ (前端页面) │ │ (端口 80) │ │ (端口 8081)│ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ │ ┌──────┴──────┐ ┌──────┴──────┐ │ 静态资源 │ │ MySQL │ │ /hmdp/ │ │ (3306) │ └─────────────┘ └─────────────┘ │ ┌──────┴──────┐ │ Redis │ │ (6379) │ └─────────────┘ │ ┌──────┴──────┐ │ RabbitMQ │ │ (5672) │ └─────────────┘ ``` ### Nginx 配置示例 ```nginx server { listen 80; server_name localhost; # 前端静态资源 location / { root /path/to/nginx/html/hmdp; index index.html; } # 后端 API 代理 location /api/ { proxy_pass http://localhost:8081/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } # 图片上传目录 location /imgs/ { alias /path/to/upload/imgs/; } } ``` ### 图片上传说明 - 本地上传路径:`SystemConstants.IMAGE_UPLOAD_DIR`(需修改为实际路径) - 阿里云 OSS:自动按年/月生成目录结构 `images/{year}/{month}/{uuid}.{suffix}` --- ## Redis 集群配置 ### 单机模式(默认) ```yaml spring: data: redis: host: localhost port: 6379 database: 1 ``` ### 集群模式 在 `application.yaml` 中启用集群配置: ```yaml redisson: multi-client: nodes: node1: address: redis://127.0.0.1:6379 database: 1 node2: address: redis://127.0.0.1:6380 database: 0 node3: address: redis://127.0.0.1:6381 database: 0 ``` ### 集群部署步骤 1. **启动多个 Redis 实例** ```bash # 实例 1 redis-server --port 6379 --daemonize yes # 实例 2 redis-server --port 6380 --daemonize yes # 实例 3 redis-server --port 6381 --daemonize yes ``` 2. **修改配置文件** - 取消 `application.yaml` 中 node2、node3 的注释 - 根据实际部署修改地址和端口 3. **Redisson 集群特性** - 自动故障转移 - 数据分片 - 读写分离 ### 注意事项 - 集群模式下,Lua 脚本操作的 key 必须在同一 slot - 当前项目的 key 设计(如 `seckill:stock:{voucherId}`)已支持集群 - 建议生产环境使用至少 3 主 3 从的集群配置 --- ## 待优化项 - [ ] 热门笔记缓存 - [ ] 阿里云短信验证码集成 - [ ] Token 有效期刷新机制 - [ ] 接口限流(Sentinel/RateLimiter) - [ ] 日志收集与监控(ELK) --- ## 许可证 MIT License