diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d5b12c9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,45 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Node ### +node_modules/ + +### Logs ### +logs/ + +### Claude Code ### +.claude/ + +### Frontend Refactor Plan ### +FRONTEND_REFACTOR_PLAN.md diff --git a/CLAUDE.md b/CLAUDE.md index 00b4333..d8e9b2e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,256 +2,198 @@ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. -## 始终使用中文回复 +## 项目概述 -- 在所有沟通和代码注释中,必须使用中文进行交流 -- 保持语言的专业性和技术准确性 +FlashSaleSystem 是一个基于 Spring Boot 2.7.6 和 Redis 集群构建的高并发秒杀系统。系统采用分布式架构设计,通过 Redis 集群实现高并发处理,使用 Lua 脚本保证原子性操作,采用分布式锁防止超卖。 -## mcp 工具使用 +## 核心架构 -- 当涉及到相关库的使用时,应该用 context7 查询相关文档 - -## Project Overview - -FlashSaleSystem is a high-concurrency flash sale (秒杀) system built with Spring Boot and Redis Cluster. The system -implements distributed architecture with anti-overselling mechanisms, rate limiting, and distributed locking using Redis -and Lua scripts. - -**Project Completion**: 90% - -## Core Architecture - -### Technology Stack - -- **Backend**: Spring Boot 2.7.6, Java 1.8 -- **Database**: MySQL 5.7+ with JPA/Hibernate -- **Cache**: Redis 6.0+ Cluster (6 nodes) with Redisson 3.24.3 -- **Frontend**: JSP + JSTL + Bootstrap 5 + jQuery -- **Build Tool**: Maven 3.6+ -- **API Documentation**: Knife4j 4.1.0 (Swagger) - -### Key Components - -- **Controllers**: Handle HTTP requests for different modules (flash sales, cart, orders, admin) -- **Services**: Business logic layer with Redis-based caching and distributed operations -- **Repositories**: JPA data access layer for MySQL operations -- **DTOs**: Data transfer objects for API communication -- **Entities**: JPA entities mapping to database tables - -### Package Structure +### 技术栈 +- **后端框架**: Spring Boot 2.7.6, Java 1.8 +- **数据库**: MySQL 5.7+ (JPA/Hibernate) +- **缓存系统**: Redis 6.0+ (支持单节点/集群/哨兵模式) +- **分布式锁**: Redisson 3.24.3 +- **前端技术**: JSP + JSTL + Bootstrap 5 + jQuery +- **API文档**: Knife4j 4.1.0 (增强版Swagger) +- **构建工具**: Maven 3.6+ +### 包结构 ``` com.org.flashsalesystem/ -├── controller/ # REST controllers and web endpoints -├── service/ # Business logic and Redis operations -├── repository/ # JPA repositories for data access -├── entity/ # JPA entities (User, Product, Order, FlashSale) -├── dto/ # Data transfer objects -├── config/ # Configuration classes (Redis, Swagger, Web) -└── util/ # Utility classes and JSP functions +├── controller/ # 控制器层(REST API和页面控制) +├── service/ # 业务逻辑层(核心业务和Redis操作) +├── repository/ # 数据访问层(JPA接口) +├── entity/ # 实体类(User, Product, Order, FlashSale) +├── dto/ # 数据传输对象 +├── config/ # 配置类(RedissonConfig, SwaggerConfig, WebConfig) +└── util/ # 工具类(JSPFunctions, PasswordGenerator) ``` -### Redis Integration - -- **Multiple Modes Supported**: Single node, Cluster (6 nodes), Sentinel -- **Mode Selection**: Automatic based on configuration in application.yml -- **Default Mode**: Single node (localhost:6379) for development -- **Cluster Configuration**: 6-node Redis cluster at 42.192.62.91:7000-7005 via RedissonConfig -- **Data Types**: String (locks, sessions), Hash (user/product info, cart), List (order queues), Set (successful users), - ZSet (rankings) -- **Lua Scripts**: Atomic operations for flash sales, distributed locks, rate limiting, cart operations -- **Message Queues**: Pub/Sub channels - order:status:change, stock:change, flashsale:result - -### Redis Key Prefixes - -- `flashsale:` - Flash sale activity data -- `flashsale_stock:` - Real-time stock information -- `flashsale_lock:` - Distributed locks for flash sales -- `flashsale_success:` - Successful user sets -- `user:` - User information cache -- `product:` - Product information cache -- `cart:` - Shopping cart data -- `rate_limit:` - API rate limiting counters - -## Common Development Commands - -### Build and Run +## 常用开发命令 +### 构建和运行 ```bash # 编译项目 mvn clean compile -# 运行应用(默认单节点Redis) -mvn spring-boot:run +# 单元测试编译 +mvn test-compile -# 运行应用(开发环境,单节点Redis) -mvn spring-boot:run -Dspring.profiles.active=dev +# 运行测试 +mvn test +mvn test -Dtest=FlashSaleServiceTest -# 运行应用(生产环境,Redis集群) -mvn spring-boot:run -Dspring.profiles.active=cluster - -# 打包应用 -mvn clean package - -# 跳过测试打包 +# 打包(跳过测试) mvn clean package -DskipTests -# 运行打包后的jar(默认配置) -java -jar target/FlashSaleSystem-0.0.1-SNAPSHOT.jar +# 本地运行(默认单节点Redis) +mvn spring-boot:run -# 运行打包后的jar(指定profile) +# 运行指定profile +mvn spring-boot:run -Dspring.profiles.active=dev # 开发环境 +mvn spring-boot:run -Dspring.profiles.active=cluster # 集群环境 + +# 运行JAR包 +java -jar target/FlashSaleSystem-0.0.1-SNAPSHOT.jar java -jar target/FlashSaleSystem-0.0.1-SNAPSHOT.jar --spring.profiles.active=cluster ``` -### Testing - -```bash -# 运行所有测试(目前无测试类,需要创建) -mvn test - -# 运行特定测试类 -mvn test -Dtest=FlashSaleServiceTest -mvn test -Dtest=RedisServiceTest - -# 运行集成测试 -mvn verify -``` - -### Database Setup - +### 数据库初始化 ```bash # 创建数据库 -mysql -u root -p -CREATE DATABASE flash_sale_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +mysql -u root -p -e "CREATE DATABASE flash_sale_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" -# 导入表结构(JPA会自动创建,但也可以手动导入) +# 导入表结构(JPA自动创建,可选) mysql -u root -p flash_sale_db < src/main/resources/sql/schema.sql # 导入测试数据 mysql -u root -p flash_sale_db < src/main/resources/sql/test-data.sql -# 导入演示用户(包含预设密码) +# 导入演示用户 mysql -u root -p flash_sale_db < src/main/resources/sql/demo-users.sql ``` -## Application Configuration +## Redis架构设计 -### Key Configuration Files +### 支持模式 +1. **单节点模式**(默认): localhost:6379,适用于开发环境 +2. **集群模式**: 6节点集群(42.192.62.91:7000-7005),生产环境推荐 +3. **哨兵模式**: 高可用配置,支持主从切换 -- `application.yml`: Main application configuration including Redis cluster, database, and custom flash sale settings -- `pom.xml`: Maven dependencies and build configuration -- `src/main/resources/lua/`: Lua scripts for Redis atomic operations +### Redis数据结构使用 +- **String**: 分布式锁、会话存储、库存计数 +- **Hash**: 用户信息、商品信息、购物车数据 +- **List**: 订单队列、消息队列 +- **Set**: 秒杀成功用户集合 +- **ZSet**: 商品排行榜、热门活动 -### Important Configuration Sections +### Key前缀规范 +- `flashsale:` - 秒杀活动数据 +- `flashsale_stock:` - 实时库存信息 +- `flashsale_lock:` - 秒杀分布式锁 +- `flashsale_success:` - 成功用户集合 +- `user:` - 用户信息缓存 +- `product:` - 商品信息缓存 +- `cart:` - 购物车数据 +- `rate_limit:` - API限流计数器 -- **Redis Mode**: Supports Single node (default), Cluster (6 nodes), Sentinel modes -- **Redis Single Node**: localhost:6379 (default for development) -- **Redis Cluster**: 6-node cluster with password authentication (6HU3cw1drNjfQ0zo1Uyx) -- **Flash Sale Settings**: Rate limiting (10 requests/minute), max quantity per user (1), stock preload (30min advance) -- **Cache TTL**: User info (30min), product info (60min), flash sale data (10min) -- **Database**: HikariCP connection pool (max 20, min 5) -- **Cart Settings**: Expire after 7 days, max 20 items +### Lua脚本(src/main/resources/lua/) +1. **flashsale.lua**: 原子性库存扣减,防止超卖 +2. **distributed_lock.lua**: 分布式锁获取 +3. **unlock.lua**: 安全释放分布式锁 +4. **rate_limit.lua**: 滑动窗口限流 +5. **cart_operation.lua**: 购物车原子操作 -### Redis Mode Switching +## 核心业务流程 -1. **Single Node Mode** (Default): - - Edit `application.yml` and ensure cluster configuration is commented out - - Or use profile: `mvn spring-boot:run -Dspring.profiles.active=dev` +### 秒杀流程 +1. **库存预热**: 活动前30分钟通过 `FlashSaleService.preloadStock()` 预加载库存到Redis +2. **限流检查**: `RateLimitService.checkFlashSaleRateLimit()` 检查用户请求频率(10次/分钟) +3. **分布式锁**: `RedissonLockService.tryLock()` 获取分布式锁,防止并发超卖 +4. **库存扣减**: 执行 `flashsale.lua` 脚本原子性扣减库存 +5. **订单创建**: 数据库创建订单,Redis记录成功用户 +6. **消息发布**: 通过Pub/Sub发布秒杀结果通知 -2. **Cluster Mode**: - - Use profile: `mvn spring-boot:run -Dspring.profiles.active=cluster` - - Or uncomment cluster configuration in `application.yml` +### 关键服务类 +- **FlashSaleService**: 秒杀核心逻辑,包含库存预热、分布式锁、Lua脚本执行 +- **RedisService**: Redis基础操作封装,支持各种数据类型和TTL设置 +- **RedissonLockService**: Redisson分布式锁实现,支持自动续期 +- **RateLimitService**: 基于Redis的滑动窗口限流 +- **CartService**: 购物车服务,基于Redis Hash实现 +- **RedisPipelineService**: 批量Redis操作优化 +- **MessageListenerService**: Redis Pub/Sub消息监听处理 -3. **Environment Variable Override**: - ```bash - export SPRING_REDIS_HOST=your-redis-host - export SPRING_REDIS_CLUSTER_NODES=node1:7000,node2:7001 - ``` +## 配置说明 -## Development Guidelines +### 核心配置文件 +- `application.yml`: 主配置文件(数据库、Redis、业务配置) +- `pom.xml`: Maven依赖和构建配置 -### Service Layer Patterns +### 重要配置项 +```yaml +# Redis模式切换(application.yml) +spring.redis.host: localhost # 单节点配置 +spring.redis.cluster.nodes: ... # 集群配置(取消注释启用) -- All Redis operations use Redisson for cluster support -- Critical operations (stock deduction, cart updates) use Lua scripts for atomicity -- Distributed locks prevent overselling using Redisson's RLock with timeout -- Rate limiting implemented via sliding window algorithm in Lua -- Use RedisPipelineService for batch operations to improve performance +# 秒杀业务配置 +flashsale.seckill.rate-limit.max-requests-per-minute: 10 # 限流 +flashsale.seckill.max-quantity-per-user: 1 # 每人限购 +flashsale.seckill.stock-preload.advance-minutes: 30 # 预热时间 -### Key Services +# 缓存过期时间 +flashsale.cache.user-expire-minutes: 30 # 用户信息 +flashsale.cache.product-expire-minutes: 60 # 商品信息 +flashsale.cache.flashsale-expire-minutes: 10 # 秒杀活动 +``` -- **FlashSaleService**: Core flash sale logic with distributed locking and Lua scripts -- **RedisService**: Generic Redis operations wrapper with TTL support -- **DistributedLockService**: Distributed locking abstraction with auto-renewal -- **RateLimitService**: API rate limiting using Redis sliding window -- **CartService**: Shopping cart operations with Redis Hash storage -- **RedisPipelineService**: Batch Redis operations using pipeline -- **MessageListenerService**: Redis Pub/Sub message handling +## 性能优化策略 -### Flash Sale Process Flow +1. **连接池优化**: HikariCP数据库连接池(20),Jedis连接池(20) +2. **批量操作**: 使用 `RedisPipelineService` 进行批量Redis操作 +3. **多级缓存**: 本地缓存 + Redis缓存,合理设置TTL +4. **Lua脚本**: 减少网络往返,保证原子性 +5. **库存预热**: 提前加载热点数据到缓存 -1. **Stock Preload**: FlashSaleService.preloadStock() loads stock to Redis 30min before -2. **Rate Limit Check**: RateLimitService.isAllowed() checks request frequency -3. **Distributed Lock**: DistributedLockService.tryLock() prevents concurrent access -4. **Stock Check**: Lua script atomically checks and deducts stock -5. **Order Creation**: Creates order in database and publishes result -6. **Cache Update**: Updates user success set and publishes notifications +## 监控和运维 -### Testing Approach +### 访问地址 +- **应用首页**: http://localhost:8080 +- **API文档**: http://localhost:8080/doc.html +- **健康检查**: http://localhost:8080/actuator/health +- **Prometheus监控**: http://localhost:8080/actuator/prometheus -- Unit tests should be created for core services (FlashSaleService, RedisService, CartService) -- Integration tests should verify Redis cluster connectivity and database operations -- Load testing recommended using JMeter for flash sale scenarios -- Mock Redis operations in unit tests using Mockito +### 日志配置 +- **日志文件**: logs/flash-sale-system.log +- **日志级别**: DEBUG (com.org.flashsalesystem, Redis, SQL) -## Lua Script Usage +## 测试策略 -The system includes 5 Lua scripts in `src/main/resources/lua/`: +### 单元测试 +- 核心服务测试: FlashSaleServiceTest (已创建框架) +- 建议补充: RedisServiceTest, CartServiceTest +- Mock策略: 使用Mockito模拟Redis和数据库操作 -- `flashsale.lua`: Atomic stock deduction with overselling prevention (returns: remaining stock or negative error codes) -- `distributed_lock.lua`: Distributed lock acquisition with expiry -- `unlock.lua`: Safe distributed lock release with owner verification -- `rate_limit.lua`: Sliding window rate limiting (returns: 1 if allowed, 0 if blocked) -- `cart_operation.lua`: Atomic shopping cart operations (add/update/remove items) +### 性能测试 +- 推荐工具: JMeter, Gatling +- 测试场景: 高并发秒杀、库存扣减准确性、分布式锁效果 -### Lua Script Error Codes +## 安全考虑 -- `-1`: Key not exists or invalid -- `-2`: Insufficient stock -- `-3`: Invalid parameter +1. **密码加密**: BCrypt (strength=10) +2. **Redis认证**: 集群模式使用密码认证 +3. **SQL注入防护**: JPA参数化查询 +4. **限流保护**: API级别限流防止恶意请求 +5. **会话管理**: Redis存储,30分钟超时 -## API Documentation +## 故障排查 -- **Swagger UI**: http://localhost:8080/doc.html (Knife4j enhanced UI) -- **API Docs**: http://localhost:8080/v3/api-docs -- **Test Endpoints**: TestController provides Redis connection and data verification endpoints +### 常见问题 +1. **Redis连接失败**: 检查网络、端口、密码配置 +2. **库存超卖**: 验证Lua脚本加载、分布式锁配置 +3. **高延迟**: 检查Redis集群状态、网络延迟 +4. **内存溢出**: 监控Redis内存、调整缓存TTL -## Monitoring and Health - -- **Actuator Endpoints**: /actuator/health, /actuator/metrics, /actuator/prometheus -- **Log Files**: logs/flash-sale-system.log with detailed Redis and SQL logging -- **Debug Level**: Enabled for com.org.flashsalesystem, org.springframework.data.redis, org.hibernate.SQL -- **Metrics Export**: Prometheus metrics enabled for monitoring - -## Security Considerations - -- **Redis Authentication**: Cluster uses password authentication -- **Database Connection**: Uses HikariCP with SSL disabled (enable for production) -- **Password Encoding**: BCrypt with strength 10 for user passwords -- **Rate Limiting**: Built-in rate limiting to prevent abuse -- **Session Management**: Redis-based session storage with 30min timeout - -## Performance Optimization - -- **Connection Pooling**: HikariCP (20 max) for DB, Jedis pool (20 max) for Redis -- **Pipeline Operations**: Use RedisPipelineService for batch operations -- **Cache Strategy**: Multi-level caching with appropriate TTL -- **Lua Scripts**: Reduce network round trips for atomic operations -- **Stock Preload**: Warm up cache before flash sale starts - -## Common Issues and Solutions - -1. **Redis Connection Failed**: Check cluster nodes accessibility and password -2. **Stock Overselling**: Ensure Lua scripts are loaded and distributed locks work -3. **High Latency**: Use pipeline for batch operations, check network latency -4. **Memory Issues**: Monitor Redis memory usage, adjust cache TTL if needed \ No newline at end of file +### 调试技巧 +- 启用DEBUG日志查看详细Redis操作 +- 使用Redis CLI监控命令: `MONITOR` +- 检查Lua脚本执行: `SCRIPT EXISTS` \ No newline at end of file diff --git a/start-system.sh b/start-system.sh new file mode 100644 index 0000000..f911d4b --- /dev/null +++ b/start-system.sh @@ -0,0 +1,119 @@ +#!/bin/bash + +# 秒杀系统启动脚本 + +echo "=========================================" +echo " 秒杀系统启动脚本 v1.0 " +echo "=========================================" +echo "" + +# 颜色定义 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# 检查Java环境 +echo -e "${YELLOW}[1/4] 检查Java环境...${NC}" +if ! command -v java &> /dev/null; then + echo -e "${RED}❌ Java未安装,请先安装JDK 1.8+${NC}" + exit 1 +fi +echo -e "${GREEN}✅ Java环境正常${NC}" + +# 检查Node环境 +echo -e "${YELLOW}[2/4] 检查Node环境...${NC}" +if ! command -v node &> /dev/null; then + echo -e "${RED}❌ Node.js未安装,请先安装Node.js 16+${NC}" + exit 1 +fi +echo -e "${GREEN}✅ Node环境正常${NC}" + +# 启动后端 +echo "" +echo -e "${YELLOW}[3/4] 启动Spring Boot后端...${NC}" +cd "$(dirname "$0")" + +# 检查8080端口是否被占用 +if lsof -Pi :8080 -sTCP:LISTEN -t >/dev/null ; then + echo -e "${YELLOW}⚠️ 端口8080已被占用,尝试停止现有服务...${NC}" + kill -9 $(lsof -t -i:8080) 2>/dev/null + sleep 2 +fi + +# 启动后端(后台运行) +echo "正在启动后端服务..." +nohup mvn spring-boot:run > logs/backend.log 2>&1 & +BACKEND_PID=$! +echo "后端PID: $BACKEND_PID" + +# 等待后端启动 +echo "等待后端服务启动..." +for i in {1..30}; do + if curl -s http://localhost:8080/actuator/health > /dev/null 2>&1; then + echo -e "${GREEN}✅ 后端服务启动成功!${NC}" + break + fi + if [ $i -eq 30 ]; then + echo -e "${RED}❌ 后端服务启动超时,请检查日志: logs/backend.log${NC}" + exit 1 + fi + sleep 1 + echo -n "." +done + +# 启动前端 +echo "" +echo -e "${YELLOW}[4/4] 启动Vue前端...${NC}" +cd flash-sale-frontend + +# 检查依赖 +if [ ! -d "node_modules" ]; then + echo "安装前端依赖..." + npm install --cache /tmp/npm-cache +fi + +# 检查3000端口 +if lsof -Pi :3000 -sTCP:LISTEN -t >/dev/null ; then + echo -e "${YELLOW}⚠️ 端口3000已被占用,使用其他端口...${NC}" +fi + +# 启动前端(后台运行) +echo "正在启动前端服务..." +nohup npm run dev > ../logs/frontend.log 2>&1 & +FRONTEND_PID=$! +echo "前端PID: $FRONTEND_PID" + +# 等待前端启动 +sleep 3 + +# 显示访问信息 +echo "" +echo "=========================================" +echo -e "${GREEN}✅ 系统启动完成!${NC}" +echo "=========================================" +echo "" +echo "访问地址:" +echo -e " 前端应用: ${GREEN}http://localhost:3000${NC} 或 ${GREEN}http://localhost:3001${NC}" +echo -e " 后端API: ${GREEN}http://localhost:8080${NC}" +echo -e " API文档: ${GREEN}http://localhost:8080/doc.html${NC}" +echo "" +echo "测试账号:" +echo " 普通用户: user / 123456" +echo " 管理员: admin / 123456" +echo "" +echo "停止服务:" +echo " 后端PID: $BACKEND_PID (kill $BACKEND_PID)" +echo " 前端PID: $FRONTEND_PID (kill $FRONTEND_PID)" +echo "" +echo "查看日志:" +echo " 后端日志: tail -f logs/backend.log" +echo " 前端日志: tail -f logs/frontend.log" +echo "" +echo "=========================================" + +# 保存PID到文件 +echo "$BACKEND_PID" > .backend.pid +echo "$FRONTEND_PID" > .frontend.pid + +echo -e "${YELLOW}提示: 使用 ./stop-system.sh 停止所有服务${NC}" \ No newline at end of file