兼容redis
This commit is contained in:
159
CLAUDE.md
159
CLAUDE.md
@@ -24,11 +24,11 @@ and Lua scripts.
|
|||||||
### Technology Stack
|
### Technology Stack
|
||||||
|
|
||||||
- **Backend**: Spring Boot 2.7.6, Java 1.8
|
- **Backend**: Spring Boot 2.7.6, Java 1.8
|
||||||
- **Database**: MySQL with JPA/Hibernate
|
- **Database**: MySQL 5.7+ with JPA/Hibernate
|
||||||
- **Cache**: Redis Cluster with Redisson
|
- **Cache**: Redis 6.0+ Cluster (6 nodes) with Redisson 3.24.3
|
||||||
- **Frontend**: JSP + JSTL + Bootstrap 5 + jQuery
|
- **Frontend**: JSP + JSTL + Bootstrap 5 + jQuery
|
||||||
- **Build Tool**: Maven
|
- **Build Tool**: Maven 3.6+
|
||||||
- **API Documentation**: Knife4j (Swagger)
|
- **API Documentation**: Knife4j 4.1.0 (Swagger)
|
||||||
|
|
||||||
### Key Components
|
### Key Components
|
||||||
|
|
||||||
@@ -53,50 +53,85 @@ com.org.flashsalesystem/
|
|||||||
|
|
||||||
### Redis Integration
|
### Redis Integration
|
||||||
|
|
||||||
- **Cluster Configuration**: Multi-node Redis cluster setup via RedissonConfig
|
- **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),
|
- **Data Types**: String (locks, sessions), Hash (user/product info, cart), List (order queues), Set (successful users),
|
||||||
ZSet (rankings)
|
ZSet (rankings)
|
||||||
- **Lua Scripts**: Atomic operations for flash sales, distributed locks, rate limiting, cart operations
|
- **Lua Scripts**: Atomic operations for flash sales, distributed locks, rate limiting, cart operations
|
||||||
- **Message Queues**: Pub/Sub for order status changes and inventory updates
|
- **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
|
## Common Development Commands
|
||||||
|
|
||||||
### Build and Run
|
### Build and Run
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Compile project
|
# 编译项目
|
||||||
mvn clean compile
|
mvn clean compile
|
||||||
|
|
||||||
# Run application
|
# 运行应用(默认单节点Redis)
|
||||||
mvn spring-boot:run
|
mvn spring-boot:run
|
||||||
|
|
||||||
# Package application
|
# 运行应用(开发环境,单节点Redis)
|
||||||
|
mvn spring-boot:run -Dspring.profiles.active=dev
|
||||||
|
|
||||||
|
# 运行应用(生产环境,Redis集群)
|
||||||
|
mvn spring-boot:run -Dspring.profiles.active=cluster
|
||||||
|
|
||||||
|
# 打包应用
|
||||||
mvn clean package
|
mvn clean package
|
||||||
|
|
||||||
|
# 跳过测试打包
|
||||||
|
mvn clean package -DskipTests
|
||||||
|
|
||||||
|
# 运行打包后的jar(默认配置)
|
||||||
|
java -jar target/FlashSaleSystem-0.0.1-SNAPSHOT.jar
|
||||||
|
|
||||||
|
# 运行打包后的jar(指定profile)
|
||||||
|
java -jar target/FlashSaleSystem-0.0.1-SNAPSHOT.jar --spring.profiles.active=cluster
|
||||||
```
|
```
|
||||||
|
|
||||||
### Testing
|
### Testing
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Run all tests (if available)
|
# 运行所有测试(目前无测试类,需要创建)
|
||||||
mvn test
|
mvn test
|
||||||
|
|
||||||
# Run specific test classes
|
# 运行特定测试类
|
||||||
mvn test -Dtest=FlashSaleServiceTest
|
mvn test -Dtest=FlashSaleServiceTest
|
||||||
mvn test -Dtest=RedisServiceTest
|
mvn test -Dtest=RedisServiceTest
|
||||||
|
|
||||||
# Note: Test classes may need to be created for comprehensive testing
|
# 运行集成测试
|
||||||
|
mvn verify
|
||||||
```
|
```
|
||||||
|
|
||||||
### Database Setup
|
### Database Setup
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Create database
|
# 创建数据库
|
||||||
mysql -u root -p
|
mysql -u root -p
|
||||||
CREATE DATABASE flash_sale_db;
|
CREATE DATABASE flash_sale_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
# Import schema and test data
|
# 导入表结构(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/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/test-data.sql
|
||||||
|
|
||||||
|
# 导入演示用户(包含预设密码)
|
||||||
|
mysql -u root -p flash_sale_db < src/main/resources/sql/demo-users.sql
|
||||||
```
|
```
|
||||||
|
|
||||||
## Application Configuration
|
## Application Configuration
|
||||||
@@ -109,10 +144,29 @@ mysql -u root -p flash_sale_db < src/main/resources/sql/test-data.sql
|
|||||||
|
|
||||||
### Important Configuration Sections
|
### Important Configuration Sections
|
||||||
|
|
||||||
- **Redis Cluster**: Configured for 6-node cluster with authentication
|
- **Redis Mode**: Supports Single node (default), Cluster (6 nodes), Sentinel modes
|
||||||
- **Flash Sale Settings**: Rate limiting (10 requests/minute), max quantity per user (1), stock preload timing
|
- **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)
|
- **Cache TTL**: User info (30min), product info (60min), flash sale data (10min)
|
||||||
- **Database**: HikariCP connection pool with optimized settings
|
- **Database**: HikariCP connection pool (max 20, min 5)
|
||||||
|
- **Cart Settings**: Expire after 7 days, max 20 items
|
||||||
|
|
||||||
|
### 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`
|
||||||
|
|
||||||
|
2. **Cluster Mode**:
|
||||||
|
- Use profile: `mvn spring-boot:run -Dspring.profiles.active=cluster`
|
||||||
|
- Or uncomment cluster configuration in `application.yml`
|
||||||
|
|
||||||
|
3. **Environment Variable Override**:
|
||||||
|
```bash
|
||||||
|
export SPRING_REDIS_HOST=your-redis-host
|
||||||
|
export SPRING_REDIS_CLUSTER_NODES=node1:7000,node2:7001
|
||||||
|
```
|
||||||
|
|
||||||
## Development Guidelines
|
## Development Guidelines
|
||||||
|
|
||||||
@@ -120,47 +174,84 @@ mysql -u root -p flash_sale_db < src/main/resources/sql/test-data.sql
|
|||||||
|
|
||||||
- All Redis operations use Redisson for cluster support
|
- All Redis operations use Redisson for cluster support
|
||||||
- Critical operations (stock deduction, cart updates) use Lua scripts for atomicity
|
- Critical operations (stock deduction, cart updates) use Lua scripts for atomicity
|
||||||
- Distributed locks prevent overselling using Redisson's RLock
|
- Distributed locks prevent overselling using Redisson's RLock with timeout
|
||||||
- Rate limiting implemented via sliding window algorithm in Lua
|
- Rate limiting implemented via sliding window algorithm in Lua
|
||||||
|
- Use RedisPipelineService for batch operations to improve performance
|
||||||
|
|
||||||
### Key Services
|
### Key Services
|
||||||
|
|
||||||
- **FlashSaleService**: Core flash sale logic with distributed locking and Lua scripts
|
- **FlashSaleService**: Core flash sale logic with distributed locking and Lua scripts
|
||||||
- **RedisService**: Generic Redis operations wrapper
|
- **RedisService**: Generic Redis operations wrapper with TTL support
|
||||||
- **DistributedLockService**: Distributed locking abstraction
|
- **DistributedLockService**: Distributed locking abstraction with auto-renewal
|
||||||
- **RateLimitService**: API rate limiting using Redis
|
- **RateLimitService**: API rate limiting using Redis sliding window
|
||||||
- **CartService**: Shopping cart operations with Redis Hash storage
|
- **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. **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
|
### Testing Approach
|
||||||
|
|
||||||
- Unit tests should be created for core services (FlashSaleService, RedisService, CartService)
|
- Unit tests should be created for core services (FlashSaleService, RedisService, CartService)
|
||||||
- Integration tests should verify Redis cluster connectivity and database operations
|
- Integration tests should verify Redis cluster connectivity and database operations
|
||||||
- Load testing recommended for flash sale scenarios to validate concurrency handling
|
- Load testing recommended using JMeter for flash sale scenarios
|
||||||
|
- Mock Redis operations in unit tests using Mockito
|
||||||
|
|
||||||
## Lua Script Usage
|
## Lua Script Usage
|
||||||
|
|
||||||
The system includes 5 Lua scripts in `src/main/resources/lua/`:
|
The system includes 5 Lua scripts in `src/main/resources/lua/`:
|
||||||
|
|
||||||
- `flashsale.lua`: Atomic stock deduction with overselling prevention
|
- `flashsale.lua`: Atomic stock deduction with overselling prevention (returns: remaining stock or negative error codes)
|
||||||
- `distributed_lock.lua`: Distributed lock acquisition
|
- `distributed_lock.lua`: Distributed lock acquisition with expiry
|
||||||
- `unlock.lua`: Safe distributed lock release
|
- `unlock.lua`: Safe distributed lock release with owner verification
|
||||||
- `rate_limit.lua`: Sliding window rate limiting
|
- `rate_limit.lua`: Sliding window rate limiting (returns: 1 if allowed, 0 if blocked)
|
||||||
- `cart_operation.lua`: Atomic shopping cart operations
|
- `cart_operation.lua`: Atomic shopping cart operations (add/update/remove items)
|
||||||
|
|
||||||
|
### Lua Script Error Codes
|
||||||
|
|
||||||
|
- `-1`: Key not exists or invalid
|
||||||
|
- `-2`: Insufficient stock
|
||||||
|
- `-3`: Invalid parameter
|
||||||
|
|
||||||
## API Documentation
|
## API Documentation
|
||||||
|
|
||||||
- **Swagger UI**: http://localhost:8080/doc.html (Knife4j)
|
- **Swagger UI**: http://localhost:8080/doc.html (Knife4j enhanced UI)
|
||||||
- **API Docs**: http://localhost:8080/v3/api-docs
|
- **API Docs**: http://localhost:8080/v3/api-docs
|
||||||
|
- **Test Endpoints**: TestController provides Redis connection and data verification endpoints
|
||||||
|
|
||||||
## Monitoring and Health
|
## Monitoring and Health
|
||||||
|
|
||||||
- **Actuator Endpoints**: /actuator/health, /actuator/metrics, /actuator/prometheus
|
- **Actuator Endpoints**: /actuator/health, /actuator/metrics, /actuator/prometheus
|
||||||
- **Log Files**: logs/flash-sale-system.log with detailed Redis and SQL logging
|
- **Log Files**: logs/flash-sale-system.log with detailed Redis and SQL logging
|
||||||
- **Debug Level**: Enabled for package com.org.flashsalesystem and Redis operations
|
- **Debug Level**: Enabled for com.org.flashsalesystem, org.springframework.data.redis, org.hibernate.SQL
|
||||||
|
- **Metrics Export**: Prometheus metrics enabled for monitoring
|
||||||
|
|
||||||
## Security Considerations
|
## Security Considerations
|
||||||
|
|
||||||
- **Redis Authentication**: Cluster uses password authentication as configured in application.yml
|
- **Redis Authentication**: Cluster uses password authentication
|
||||||
- **Database Connection**: Uses HikariCP with connection pooling and timeout configurations
|
- **Database Connection**: Uses HikariCP with SSL disabled (enable for production)
|
||||||
- **Password Encoding**: Spring Security crypto for password hashing
|
- **Password Encoding**: BCrypt with strength 10 for user passwords
|
||||||
- **Rate Limiting**: Built-in rate limiting to prevent abuse of flash sale endpoints
|
- **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
|
||||||
110
docs/Redis配置指南.md
Normal file
110
docs/Redis配置指南.md
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
# Redis配置说明
|
||||||
|
|
||||||
|
本项目支持三种Redis部署模式:单节点模式、集群模式和哨兵模式。
|
||||||
|
|
||||||
|
## 配置方式
|
||||||
|
|
||||||
|
### 1. 单节点模式(默认)
|
||||||
|
|
||||||
|
默认配置文件 `application.yml` 已配置为单节点模式:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
spring:
|
||||||
|
redis:
|
||||||
|
host: localhost
|
||||||
|
port: 6379
|
||||||
|
database: 0
|
||||||
|
password: your-password
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 集群模式
|
||||||
|
|
||||||
|
使用 `application-cluster.yml` 配置文件:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 运行时指定profile
|
||||||
|
java -jar FlashSaleSystem.jar --spring.profiles.active=cluster
|
||||||
|
|
||||||
|
# 或设置环境变量
|
||||||
|
export SPRING_PROFILES_ACTIVE=cluster
|
||||||
|
java -jar FlashSaleSystem.jar
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 哨兵模式
|
||||||
|
|
||||||
|
在 `application.yml` 中启用哨兵配置:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
spring:
|
||||||
|
redis:
|
||||||
|
sentinel:
|
||||||
|
master: mymaster
|
||||||
|
nodes: localhost:26379,localhost:26380,localhost:26381
|
||||||
|
password: your-password
|
||||||
|
```
|
||||||
|
|
||||||
|
## 切换Redis模式
|
||||||
|
|
||||||
|
### 方式一:修改application.yml
|
||||||
|
|
||||||
|
直接编辑 `src/main/resources/application.yml`,注释/取消注释相应配置块。
|
||||||
|
|
||||||
|
### 方式二:使用Spring Profile
|
||||||
|
|
||||||
|
1. 本地开发(单节点):
|
||||||
|
```bash
|
||||||
|
mvn spring-boot:run -Dspring.profiles.active=dev
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 生产环境(集群):
|
||||||
|
```bash
|
||||||
|
mvn spring-boot:run -Dspring.profiles.active=cluster
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方式三:环境变量覆盖
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 覆盖Redis主机
|
||||||
|
export SPRING_REDIS_HOST=192.168.1.100
|
||||||
|
export SPRING_REDIS_PORT=6379
|
||||||
|
|
||||||
|
# 覆盖为集群模式
|
||||||
|
export SPRING_REDIS_CLUSTER_NODES=192.168.1.100:7000,192.168.1.100:7001
|
||||||
|
|
||||||
|
java -jar FlashSaleSystem.jar
|
||||||
|
```
|
||||||
|
|
||||||
|
## 配置优先级
|
||||||
|
|
||||||
|
1. 命令行参数(最高优先级)
|
||||||
|
2. 环境变量
|
||||||
|
3. application-{profile}.yml
|
||||||
|
4. application.yml(最低优先级)
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. **单节点模式**:适合开发和测试环境,不建议生产使用
|
||||||
|
2. **集群模式**:推荐生产环境使用,提供高可用性
|
||||||
|
3. **密码配置**:生产环境建议使用环境变量配置密码
|
||||||
|
4. **连接池**:根据实际负载调整连接池参数
|
||||||
|
|
||||||
|
## 验证Redis连接
|
||||||
|
|
||||||
|
启动应用后,可以通过以下方式验证:
|
||||||
|
|
||||||
|
1. 查看启动日志:
|
||||||
|
```
|
||||||
|
初始化Redisson客户端...
|
||||||
|
配置Redis单机模式: localhost:6379
|
||||||
|
Redisson客户端初始化完成
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 访问测试接口:
|
||||||
|
```
|
||||||
|
GET http://localhost:8080/api/test/redis/connection
|
||||||
|
```
|
||||||
|
|
||||||
|
3. 检查健康状态:
|
||||||
|
```
|
||||||
|
GET http://localhost:8080/actuator/health
|
||||||
|
```
|
||||||
@@ -30,11 +30,22 @@ spring:
|
|||||||
dialect: org.hibernate.dialect.MySQL8Dialect
|
dialect: org.hibernate.dialect.MySQL8Dialect
|
||||||
format_sql: true
|
format_sql: true
|
||||||
|
|
||||||
# Redis集群配置
|
# Redis配置(支持单节点和集群模式)
|
||||||
redis:
|
redis:
|
||||||
cluster:
|
# 模式选择:single(单节点)、cluster(集群)
|
||||||
nodes: 42.192.62.91:7000,42.192.62.91:7001,42.192.62.91:7002,42.192.62.91:7003,42.192.62.91:7004,42.192.62.91:7005
|
# 注释掉cluster配置即自动使用单节点模式
|
||||||
password: 6HU3cw1drNjfQ0zo1Uyx
|
|
||||||
|
# === 单节点配置(默认) ===
|
||||||
|
host: localhost
|
||||||
|
port: 6379
|
||||||
|
database: 0
|
||||||
|
|
||||||
|
# === 集群配置(使用时取消注释) ===
|
||||||
|
# cluster:
|
||||||
|
# nodes: 42.192.62.91:7000,42.192.62.91:7001,42.192.62.91:7002,42.192.62.91:7003,42.192.62.91:7004,42.192.62.91:7005
|
||||||
|
|
||||||
|
# 通用配置
|
||||||
|
password:
|
||||||
timeout: 5000
|
timeout: 5000
|
||||||
jedis:
|
jedis:
|
||||||
pool:
|
pool:
|
||||||
|
|||||||
Reference in New Issue
Block a user