本文目录导读:

我来为您设计一个Java大促(例如双11、618)的系统案例,包含核心业务场景、技术架构和代码示例。
大促系统核心业务场景
// 1. 秒杀系统 // 2. 优惠券系统 // 3. 订单系统 // 4. 库存系统 // 5. 支付系统 // 6. 消息推送系统
核心技术架构
// 技术栈 - Spring Cloud Alibaba (微服务) - Redis (缓存/分布式锁) - RabbitMQ/Kafka (消息队列) - MySQL + MyBatis Plus - Nginx + LVS (负载均衡) - 分库分表 (ShardingSphere) - 分布式事务 (Seata)
核心代码实现
秒杀系统实现
/**
* 秒杀控制器
*/
@RestController
@RequestMapping("/seckill")
public class SeckillController {
@Autowired
private SeckillService seckillService;
/**
* 秒杀接口 - 使用令牌桶限流
*/
@PostMapping("/doSeckill")
@RateLimiter(limit = 100, timeout = 1000) // 自定义限流注解
public Result doSeckill(@RequestParam("userId") Long userId,
@RequestParam("productId") Long productId) {
try {
// 1. 前置校验
Result validateResult = seckillService.validateSeckill(userId, productId);
if (!validateResult.isSuccess()) {
return validateResult;
}
// 2. 执行秒杀
SeckillResult result = seckillService.executeSeckill(userId, productId);
// 3. 异步处理订单
if (result.isSuccess()) {
seckillService.asyncProcessOrder(result.getOrderId());
}
return Result.success(result);
} catch (Exception e) {
log.error("秒杀异常", e);
return Result.error("秒杀失败");
}
}
}
/**
* 秒杀服务实现
*/
@Service
public class SeckillServiceImpl implements SeckillService {
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private ProductMapper productMapper;
@Autowired
private OrderMapper orderMapper;
/**
* 秒杀核心逻辑
*/
@Override
@Transactional(rollbackFor = Exception.class)
public SeckillResult executeSeckill(Long userId, Long productId) {
// 1. Redis预减库存
Long stock = redisTemplate.opsForValue()
.decrement("seckill_stock_" + productId);
if (stock < 0) {
// 库存不足,回补
redisTemplate.opsForValue().increment("seckill_stock_" + productId);
return SeckillResult.error("商品已售罄");
}
// 2. 防止用户重复秒杀
Boolean ifAbsent = redisTemplate.opsForValue()
.setIfAbsent("seckill_user_" + userId + "_" + productId,
"1", 10, TimeUnit.MINUTES);
if (Boolean.FALSE.equals(ifAbsent)) {
return SeckillResult.error("请勿重复秒杀");
}
// 3. 发送消息到MQ异步创建订单
SeckillMessage message = new SeckillMessage();
message.setUserId(userId);
message.setProductId(productId);
rabbitTemplate.convertAndSend("seckill.exchange",
"seckill.order", message);
return SeckillResult.success("秒杀成功");
}
/**
* 预减库存 - 使用Lua脚本保证原子性
*/
public boolean preReduceStock(Long productId, Integer quantity) {
String script = "local stock = redis.call('get', KEYS[1]);" +
"if (stock - ARGV[1] >= 0) then" +
" redis.call('decrby', KEYS[1], ARGV[1]);" +
" return 1;" +
"end;" +
"return 0;";
Long result = redisTemplate.execute(
new DefaultRedisScript<>(script, Long.class),
Arrays.asList("product_stock_" + productId),
quantity.toString()
);
return result == 1;
}
}
分布式锁实现
/**
* 分布式锁工具类
*/
@Component
public class RedisLockUtil {
@Autowired
private StringRedisTemplate redisTemplate;
/**
* 基于Redis的分布式锁
*/
public boolean tryLock(String lockKey, String requestId,
long expireTime, TimeUnit timeUnit) {
Boolean success = redisTemplate.opsForValue()
.setIfAbsent(lockKey, requestId, expireTime, timeUnit);
return Boolean.TRUE.equals(success);
}
/**
* 释放锁 - Lua脚本保证原子性
*/
public boolean releaseLock(String lockKey, String requestId) {
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
"return redis.call('del', KEYS[1]) else return 0 end";
Long result = redisTemplate.execute(
new DefaultRedisScript<>(script, Long.class),
Arrays.asList(lockKey),
requestId
);
return result > 0;
}
/**
* 使用示例
*/
public void businessWithLock() {
String lockKey = "business_lock";
String requestId = UUID.randomUUID().toString();
try {
// 尝试获取锁,等待5秒
boolean locked = tryLock(lockKey, requestId, 10, TimeUnit.SECONDS);
if (!locked) {
throw new RuntimeException("获取锁失败");
}
// 业务逻辑
System.out.println("执行关键业务");
} finally {
// 释放锁
releaseLock(lockKey, requestId);
}
}
}
优惠券系统
/**
* 优惠券服务
*/
@Service
public class CouponService {
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private CouponMapper couponMapper;
/**
* 发放优惠券 - 异步批量发放
*/
@Async("couponExecutor")
public CompletableFuture<Void> batchIssueCoupons(List<Long> userIds,
Long couponTemplateId) {
// 使用Redis流水线批量处理
redisTemplate.executePipelined((RedisCallback<Object>) connection -> {
for (Long userId : userIds) {
String key = "user_coupon_" + userId;
connection.rPush(key.getBytes(),
couponTemplateId.toString().getBytes());
}
return null;
});
return CompletableFuture.completedFuture(null);
}
/**
* 领取优惠券 - 防止超发
*/
public Result claimCoupon(Long userId, Long couponId) {
// 使用分布式锁防止超发
String lockKey = "coupon_lock_" + couponId;
String requestId = UUID.randomUUID().toString();
if (!redisLockUtil.tryLock(lockKey, requestId, 5, TimeUnit.SECONDS)) {
return Result.error("系统繁忙");
}
try {
// 检查优惠券库存
Long stock = redisTemplate.opsForValue()
.decrement("coupon_stock_" + couponId);
if (stock < 0) {
return Result.error("优惠券已被抢完");
}
// 保存用户优惠券
UserCoupon userCoupon = new UserCoupon();
userCoupon.setUserId(userId);
userCoupon.setCouponTemplateId(couponId);
userCoupon.setStatus(1);
userCoupon.setCreateTime(new Date());
couponMapper.insert(userCoupon);
return Result.success("领取成功");
} finally {
redisLockUtil.releaseLock(lockKey, requestId);
}
}
}
订单异步处理
/**
* 订单消息消费者
*/
@Component
public class OrderMessageConsumer {
@Autowired
private OrderService orderService;
@Autowired
private StockService stockService;
/**
* 秒杀订单消息处理
*/
@RabbitListener(queues = "seckill.order.queue")
public void handleSeckillOrder(SeckillMessage message) {
log.info("开始处理秒杀订单: {}", message);
try {
// 1. 创建订单
Order order = new Order();
order.setUserId(message.getUserId());
order.setProductId(message.getProductId());
order.setStatus(OrderStatus.CREATED);
order.setCreateTime(new Date());
orderService.createOrder(order);
// 2. 扣减数据库库存(最终一致性)
stockService.deductStock(message.getProductId(), 1);
// 3. 发送创建成功消息
rabbitTemplate.convertAndSend("order.exchange",
"order.created", order);
} catch (Exception e) {
log.error("处理秒杀订单失败", e);
// 重新入队或标记为失败
message.setRetryCount(message.getRetryCount() + 1);
if (message.getRetryCount() < 3) {
rabbitTemplate.convertAndSend("seckill.exchange",
"seckill.delay.order", message);
}
}
}
/**
* 订单超时取消
*/
@RabbitListener(queues = "order.delay.queue")
public void handleOrderTimeout(Long orderId) {
Order order = orderService.getById(orderId);
if (order != null && order.getStatus() == OrderStatus.CREATED) {
// 取消订单
orderService.cancelOrder(orderId);
// 恢复库存
stockService.restoreStock(order.getProductId(), 1);
}
}
}
热点数据缓存
/**
* 商品缓存服务
*/
@Service
public class ProductCacheService {
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private ProductMapper productMapper;
private static final String PRODUCT_CACHE_KEY = "product:detail:";
/**
* 商品详情缓存 - 使用Caffeine本地缓存 + Redis
*/
@Cacheable(value = "productDetail", key = "#productId")
public ProductDetail getProductDetail(Long productId) {
// 1. 先从本地缓存获取
ProductDetail localCache = getFromLocalCache(productId);
if (localCache != null) {
return localCache;
}
// 2. 从Redis缓存获取
String redisKey = PRODUCT_CACHE_KEY + productId;
ProductDetail redisCache = getFromRedis(redisKey);
if (redisCache != null) {
// 异步更新本地缓存
updateLocalCache(productId, redisCache);
return redisCache;
}
// 3. 从数据库查询(使用分布式锁防止缓存击穿)
String lockKey = "product_lock_" + productId;
String requestId = UUID.randomUUID().toString();
if (redisLockUtil.tryLock(lockKey, requestId, 5, TimeUnit.SECONDS)) {
try {
// 双重检查
ProductDetail dbCache = getFromRedis(redisKey);
if (dbCache != null) {
return dbCache;
}
// 查询数据库
ProductDetail detail = productMapper.getDetail(productId);
// 空值缓存(防止缓存穿透)
if (detail == null) {
redisTemplate.opsForValue()
.set(redisKey, "", 60, TimeUnit.SECONDS);
return null;
}
// 缓存到Redis(设置随机过期时间防止雪崩)
int expireTime = 300 + new Random().nextInt(300);
redisTemplate.opsForValue()
.set(redisKey, JSON.toJSONString(detail),
expireTime, TimeUnit.SECONDS);
return detail;
} finally {
redisLockUtil.releaseLock(lockKey, requestId);
}
}
// 获取锁失败,返回默认值
return getDefaultProductDetail(productId);
}
}
流量控制与降级
/**
* 熔断降级配置
*/
@Configuration
public class ResilienceConfig {
/**
* 熔断器配置
*/
@Bean
public Customizer<Resilience4JCircuitBreakerFactory> circuitBreakerConfig() {
return factory -> factory.configureDefault(
id -> new Resilience4JConfigBuilder(id)
.circuitBreakerConfig(
io.github.resilience4j.circuitbreaker.CircuitBreakerConfig.custom()
.failureRateThreshold(50) // 失败率阈值
.waitDurationInOpenState(Duration.ofMillis(10000)) // 熔断时间
.slidingWindowSize(100) // 滑动窗口大小
.build()
)
.timeLimiterConfig(
TimeLimiterConfig.custom()
.timeoutDuration(Duration.ofSeconds(3))
.build()
)
.build()
);
}
/**
* 使用示例
*/
@CircuitBreaker(name = "productService", fallbackMethod = "fallback")
public Product getProduct(Long productId) {
// 调用微服务
return restTemplate.getForObject(
"http://product-service/product/" + productId,
Product.class
);
}
/**
* 降级方法
*/
public Product fallback(Long productId, Throwable t) {
log.error("获取商品信息失败,使用降级数据: {}", productId, t);
Product fallbackProduct = new Product();
fallbackProduct.setId(productId);
fallbackProduct.setName("热门商品");
fallbackProduct.setPrice(new BigDecimal("0.01"));
return fallbackProduct;
}
}
数据库分库分表
/**
* 分片策略配置
*/
@Configuration
public class ShardingConfig {
/**
* 订单表分片策略(按用户ID)
*/
@Bean
public ShardingRuleConfiguration orderShardingRule() {
ShardingRuleConfiguration config = new ShardingRuleConfiguration();
// 订单表配置
TableRuleConfiguration orderTableRule = new TableRuleConfiguration(
"t_order", "ds0.t_order_$->{0..4}");
// 分片算法:按用户ID取模
orderTableRule.setTableShardingStrategyConfig(
new InlineShardingStrategyConfiguration("user_id", "t_order_user_id_$->{user_id % 5}"));
config.getTableRuleConfigs().add(orderTableRule);
return config;
}
/**
* 订单查询优化 - 使用用户ID路由
*/
@Service
public class OrderQueryService {
@Autowired
private OrderMapper orderMapper;
public List<Order> getOrdersByUserId(Long userId) {
// 直接按用户ID查询(会路由到正确的分片)
return orderMapper.selectByUserId(userId);
}
public Order getOrderById(Long orderId) {
// 如果是按订单号查询,需要同时提供用户ID
// 或在订单号中嵌入分片信息
return orderMapper.selectByOrderId(orderId);
}
}
}
性能优化策略
@Component
public class PerformanceOptimizer {
/**
* 1. 多级缓存策略
*/
public void cacheStrategy() {
// 本地缓存(Caffeine)- 1分钟
Cache<String, Object> localCache = Caffeine.newBuilder()
.maximumSize(10_000)
.expireAfterWrite(1, TimeUnit.MINUTES)
.build();
// Redis缓存 - 5分钟
// 数据库 - 永久
}
/**
* 2. 批量处理优化
*/
public void batchOptimize() {
// 批量插入
List<Order> orders = new ArrayList<>();
sqlSessionTemplate.insert("batchInsertOrders", orders);
// 批量查询
List<Long> userIds = Arrays.asList(1L, 2L, 3L);
List<User> users = userMapper.selectBatchIds(userIds);
}
/**
* 3. 动态配置调整
*/
@Autowired
private NacosConfigService configService;
public void dynamicConfig() {
// 动态调整限流阈值
String rateLimit = configService.getConfig("seckill.rate.limit",
"DEFAULT_GROUP", 5000);
// 动态调整线程池大小
String threadPoolSize = configService.getConfig("seckill.thread.pool",
"DEFAULT_GROUP", 200);
}
}
监控与告警
/**
* 大促监控指标
*/
@Component
public class PrometheusMetrics {
private final Counter seckillRequests;
private final Counter seckillSuccess;
private final Counter seckillFail;
private final Gauge systemQPS;
public PrometheusMetrics() {
// 秒杀请求数
seckillRequests = Counter.build()
.name("seckill_requests_total")
.help("Total seckill requests")
.register();
// 秒杀成功数
seckillSuccess = Counter.build()
.name("seckill_success_total")
.help("Total success seckill")
.register();
// 秒杀失败数
seckillFail = Counter.build()
.name("seckill_fail_total")
.help("Total fail seckill")
.register();
// QPS监控
systemQPS = Gauge.build()
.name("system_qps")
.help("Current QPS")
.register();
}
}
高可用方案
/**
* 大促保障策略
*/
@Configuration
public class HighAvailabilityConfig {
/**
* 1. 多地域部署
* 2. 多活架构
* 3. 弹性伸缩
* 4. 链路追踪
*/
/**
* 全链路压测
*/
@Test
public void performanceTest() {
// 使用JMeter或阿里云PTS进行压测
// 每秒并发请求数
int concurrency = 10000;
// 模拟用户行为
// 1. 浏览商品
// 2. 加入购物车
// 3. 下单
// 4. 支付
}
/**
* 容灾演练
*/
public void disasterRecovery() {
// 1. 模拟Redis宕机
// 2. 模拟MySQL宕机
// 3. 模拟MQ宕机
// 4. 验证降级方案
}
}
这个Java大促案例涵盖了:
- 秒杀系统:Redis预减库存 + MQ异步处理
- 分布式锁:防止超卖和重复操作
- 优惠券系统:异步批量发放
- 订单处理:消息队列异步解耦
- 缓存优化:多级缓存防击穿
- 熔断降级:保障系统稳定
- 分库分表:处理大数据量
- 监控告警:实时掌握系统状态
您可以根据实际业务需求,选择合适的模块进行实现和优化。