兼容redis

This commit is contained in:
2025-07-29 22:13:47 +08:00
parent fd7834821e
commit c02e3421ad
3 changed files with 250 additions and 38 deletions

159
CLAUDE.md
View File

@@ -24,11 +24,11 @@ and Lua scripts.
### Technology Stack
- **Backend**: Spring Boot 2.7.6, Java 1.8
- **Database**: MySQL with JPA/Hibernate
- **Cache**: Redis Cluster with Redisson
- **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
- **API Documentation**: Knife4j (Swagger)
- **Build Tool**: Maven 3.6+
- **API Documentation**: Knife4j 4.1.0 (Swagger)
### Key Components
@@ -53,50 +53,85 @@ com.org.flashsalesystem/
### 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),
ZSet (rankings)
- **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
### Build and Run
```bash
# Compile project
# 编译项目
mvn clean compile
# Run application
# 运行应用默认单节点Redis
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 -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
```bash
# Run all tests (if available)
# 运行所有测试(目前无测试类,需要创建)
mvn test
# Run specific test classes
# 运行特定测试类
mvn test -Dtest=FlashSaleServiceTest
mvn test -Dtest=RedisServiceTest
# Note: Test classes may need to be created for comprehensive testing
# 运行集成测试
mvn verify
```
### Database Setup
```bash
# Create database
# 创建数据库
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/test-data.sql
# 导入演示用户(包含预设密码)
mysql -u root -p flash_sale_db < src/main/resources/sql/demo-users.sql
```
## Application Configuration
@@ -109,10 +144,29 @@ mysql -u root -p flash_sale_db < src/main/resources/sql/test-data.sql
### Important Configuration Sections
- **Redis Cluster**: Configured for 6-node cluster with authentication
- **Flash Sale Settings**: Rate limiting (10 requests/minute), max quantity per user (1), stock preload timing
- **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 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
@@ -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
- 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
- Use RedisPipelineService for batch operations to improve performance
### Key Services
- **FlashSaleService**: Core flash sale logic with distributed locking and Lua scripts
- **RedisService**: Generic Redis operations wrapper
- **DistributedLockService**: Distributed locking abstraction
- **RateLimitService**: API rate limiting using Redis
- **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. **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
- Unit tests should be created for core services (FlashSaleService, RedisService, CartService)
- 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
The system includes 5 Lua scripts in `src/main/resources/lua/`:
- `flashsale.lua`: Atomic stock deduction with overselling prevention
- `distributed_lock.lua`: Distributed lock acquisition
- `unlock.lua`: Safe distributed lock release
- `rate_limit.lua`: Sliding window rate limiting
- `cart_operation.lua`: Atomic shopping cart operations
- `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)
### Lua Script Error Codes
- `-1`: Key not exists or invalid
- `-2`: Insufficient stock
- `-3`: Invalid parameter
## 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
- **Test Endpoints**: TestController provides Redis connection and data verification endpoints
## 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 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
- **Redis Authentication**: Cluster uses password authentication as configured in application.yml
- **Database Connection**: Uses HikariCP with connection pooling and timeout configurations
- **Password Encoding**: Spring Security crypto for password hashing
- **Rate Limiting**: Built-in rate limiting to prevent abuse of flash sale endpoints
- **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

110
docs/Redis配置指南.md Normal file
View 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
```

View File

@@ -30,11 +30,22 @@ spring:
dialect: org.hibernate.dialect.MySQL8Dialect
format_sql: true
# Redis集群配置
# Redis配置(支持单节点和集群模式)
redis:
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: 6HU3cw1drNjfQ0zo1Uyx
# 模式选择single单节点cluster(集群)
# 注释掉cluster配置即自动使用单节点模式
# === 单节点配置(默认) ===
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
jedis:
pool: