上一篇博客介绍了使用消息队列、异步处理等技术构建 Java 电商秒杀系统的基本思路,本文将进一步优化代码实现,并提供更详细的代码示例和 RabbitMQ 配置,助您构建更健壮、高效的秒杀系统。
一、 代码优化
1. 接口限流
在 SeckillController
中使用 Guava RateLimiter 对秒杀接口进行限流,防止恶意请求压垮系统:
@Controller
public class SeckillController {
private RateLimiter rateLimiter = RateLimiter.create(1000); // 设置每秒允许 1000 个请求
@PostMapping("/seckill/{productId}")
public String seckill(@PathVariable Long productId) {
// 限流
if (!rateLimiter.tryAcquire()) {
return "请求过于频繁,请稍后再试";
}
// ... 其他逻辑 ...
}
}
2. 分布式锁
使用 Redis 实现分布式锁,保证库存扣减的原子性:
@Service
public class ProductService {
@Autowired
private RedissonClient redissonClient; // 使用 Redisson 框架操作 Redis
public void reduceStock(Long productId) {
RLock lock = redissonClient.getLock("seckill:product:" + productId);
try {
lock.lock(); // 获取锁
// ... 库存校验与扣减逻辑 ...
} finally {
lock.unlock(); // 释放锁
}
}
}
3. 异步处理优化
使用不同的队列处理不同类型的消息,提高消息处理效率:
seckillQueue
: 处理秒杀请求。orderCreateQueue
: 处理订单生成。orderCancelQueue
: 处理订单超时取消。
@Configuration
public class RabbitMQConfig {
@Bean
public Queue seckillQueue() {
return new Queue("seckillQueue");
}
@Bean
public Queue orderCreateQueue() {
return new Queue("orderCreateQueue");
}
@Bean
public Queue orderCancelQueue() {
return QueueBuilder.durable("orderCancelQueue")
.withArgument("x-dead-letter-exchange", "deadLetterExchange") // 设置死信交换机
.withArgument("x-dead-letter-routing-key", "deadLetterRoutingKey") // 设置死信路由键
.build();
}
// ... 其他配置 ...
}
4. 消息可靠性保障
- 设置消息持久化,防止消息丢失:
@Component
public class SeckillOrderConsumer {
@RabbitListener(queues = "seckillQueue")
@Transactional // 保证消息消费和业务操作的原子性
public void processSeckillOrder(Long productId) {
Channel channel = (Channel) rabbitTemplate.getConnectionFactory().createConnection().createChannel(false);
try {
// 手动确认消息
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
} catch (IOException e) {
// 处理异常,例如将消息重新放入队列
channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
}
}
}
- 使用消息确认机制,确保消息被消费:
@Configuration
public class RabbitMQConfig {
// ...
@Bean
public MessageConverter jsonMessageConverter() {
return new Jackson2JsonMessageConverter();
}
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate template = new RabbitTemplate(connectionFactory);
template.setMessageConverter(jsonMessageConverter());
// 设置消息确认模式
template.setConfirmCallback((correlationData, ack, cause) -> {
if (!ack) {
// 处理消息发送失败的情况
log.error("消息发送失败,correlationData: {}, cause: {}", correlationData, cause);
}
});
return template;
}
// ...
}
二、 RabbitMQ 配置
在 application.yml
文件中配置 RabbitMQ 相关信息:
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
listener:
simple:
acknowledge-mode: manual # 手动确认消息
template:
mandatory: true # 确保消息路由到队列,否则抛出异常
三、 总结
本文介绍了如何优化 Java 电商秒杀系统的代码实现和 RabbitMQ 配置,包括接口限流、分布式锁、异步处理优化和消息可靠性保障等方面。希望这些优化措施可以帮助您构建更加稳定、高效的秒杀系统。
当然,实际的秒杀系统设计需要根据具体的业务场景和技术架构进行调整和优化。建议您在实践中不断学习和探索,打造出更加完善的秒杀系统。