【秒杀项目5】服务优化模块

系列文章目录

`
刚入门Java的硕士宝宝,实验室没什么Java项目,看到网上的秒杀项目,跟着学习并且记录一下,可能错误会很多,欢迎大家指正。



前言

本文介绍服务优化模块,具体详细介绍RabbitMQ的使用、接口优化。


`

一、RabbitMQ

RabbitMQ 是一个开源的消息代理软件,实现了高级消息队列协议(AMQP)标准,广泛应用于分布式系统中,用于实现消息的发布与订阅、消息的队列和路由、消息的确认和重试等功能。

RabbitMQ的使用

  1. 添加依赖:
<!-- AMQP依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
  1. 配置类:
@Configuration
public class RabbitMQConfig {
   @Bean
   public Queue queue(){
      return new Queue("queue",true);
   }
}
  1. 发送消息:
@Service
@Slf4j
public class MQSender {
   @Autowired
   private RabbitTemplate rabbitTemplate;
   public void send(Object msg) {
      log.info("发送消息:"+msg);
      rabbitTemplate.convertAndSend("queue", msg);
   }
}
  1. 接收消息:
@Service
@Slf4j
public class MQReceiver {
   @RabbitListener(queues = "queue")
   public void receive(Object msg) {
      log.info("接受消息:" + msg);
   }
}
  1. 测试发送RabbitMQ消息:
@RequestMapping("/mq")
@ResponseBody
public void mq() {
   mqSender.send("Hello");
}

二、RabbitMQ 交换机

  1. Fanout模式

不处理路由键,只需要简单的将队里绑定到交换机上;
发送到交换机的消息都会被转发到与该交换机绑定的所有队列上;
Fanout交换机转发消息是最快的。

  1. Direct模式

所有发送到Direct Exchange的消息被转发到RouteKey中指定的Queue;
Direct模式可以使用RabbitMQ自带的Exchange:default Exchange,所以不需要将Exchange进行任何绑定(binding)操作,消息传递时,RouteKey必须完全匹配才会被队列接收,否则该消息会被抛弃;
routing key与队列queues 的key保持一致,即可以路由到对应的queue。

  1. Topic模式

所有发送到Topic Exchange的消息被转发到所有管线RouteKey中指定Topic的Queue上;
Exchange将RouteKey和某Topic进行模糊匹配,此时队列需要绑定一个Topic。

  1. Headers模式

不依赖routingkey,使用发送消息时basicProperties对象中的headers匹配队列;
headers是一个键值对类型,键值对的值可以是任何类型;
在队列绑定交换机时用x-match来指定,all代表定义的多个键值对都要满足,any则代表只要满足一个可以了。

三、接口优化

总目标:减少数据库访问

  1. 系统初始化,把商品库存数量加载到Redis
  2. 收到请求,Redis预减库存。库存不足,直接返回。否则进入第3步
  3. 请求入队,立即返回排队中
  4. 请求出队,生成订单,减少库存
  5. 客户端轮询,是否秒杀成功

RabbitMQ秒杀

@Configuration
public class RabbitMQConfig {
   private static final String QUEUE = "seckillQueue";
   private static final String EXCHANGE = "seckillExchange";
   @Bean
   public Queue queue(){
      return new Queue(QUEUE);
   }
   @Bean
   public TopicExchange topicExchange(){
      return new TopicExchange(EXCHANGE);
   }
   @Bean
   public Binding binding01(){
      return BindingBuilder.bind(queue()).to(topicExchange()).with("seckill.#");
   }
}
@Service
@Slf4j
public class MQSender {
   @Autowired
   private RabbitTemplate rabbitTemplate;
   public void sendsecKillMessage(String message) {
      log.info("发送消息:" + message);
      rabbitTemplate.convertAndSend("seckillExchange", "seckill.msg", message);
   }
}
@Service
@Slf4j
public class MQReceiver {
   @Autowired
   private IGoodsService goodsService;
   @Autowired
   private RedisTemplate redisTemplate;
   @Autowired
   private IOrderService orderService;
   @RabbitListener(queues = "seckillQueue")
   public void receive(String msg) {
      log.info("QUEUE接受消息:" + msg);
      SeckillMessage message = JsonUtil.jsonStr2Object(msg, SeckillMessage.class);
      Long goodsId = message.getGoodsId();
      User user = message.getUser();
      GoodsVo goods = goodsService.findGoodsVoByGoodsId(goodsId);
      //判断库存
      if (goods.getStockCount() < 1) {
         return;
     }
      String seckillOrderJson = (String) 
redisTemplate.opsForValue().get("order:" + user.getId() + ":" + goodsId);
      if (!StringUtils.isEmpty(seckillOrderJson)) {
         return;
     }
      orderService.seckill(user, goods);
   }
}

总结

以上就是今天要讲的内容,本文简单介绍了服务优化模块,具体参考 乐字节 Java电商秒杀项目。

  • 15
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值