秒杀总结(请勿参考)

秒杀总结:

前端:页面分为静态的html部分和参与秒杀的web接口

通常静态页面html通过cdn部署,所以压力不大,一般是我们后台请求接口的瓶颈。

后端:

过滤请求:

同一个用户发送多次请求

  • 方案一:redis缓存这个信息,保证请求一次
  • 方案二:将同一个账号的信息放入一个队列里,一个一个处理

多个用户多个请求:

  • 方案一:用机器检测ip频率,如果频率很高,谈验证码或者禁用ip(同一个ip)

  • 方案二:如果发现账号相连或者活跃度不高,没有资格,也可以通过风控,就是通过数据挖掘查看黄牛党的相似特征(不同ip)

请求处理:

两个需要注意的点:高并发,超卖

高并发

使用rabbitmq进行消峰。controller生产者

	@RequestMapping("/seckill/manage")
    public SysResult startSeckill(Order order){
        //查看商品是否开始售卖
        String saleStatusKey = env.getProperty("seckill.redis.key.prefix") + order.getGoodsId();
        // 1代表售卖中,0代表未开始,-1代表已结束
        String saleStatus = redisTemplate.opsForValue().get(saleStatusKey));
        if(!"1".equal()){
            return "0".equal(saleStatus) ? SysResult.error(9001,"活动未开始"):SysResult.error(9002,"活动已结束");
        }
        //如果只允许一个用户秒杀一次 可以使用redis
        String key = env.getProperty("seckill.redis.key.prefix") + order.getUserId() + order.getGoodsId();
        // 用分布式锁查看用户是否已经抢购,如果是限时抢购,需要加上失效时间
        boolean checkSeckillUser =  redisTemplate.opsForValue().setIfAbsent(key,"1");
        if(!checkSeckillUser){
           return SysResult.error(9005,"您已经参加过了"); 
        }
        //String msg=userId+"/"+seckillId;
        // 把消息发送给订单消息队列
        //设置交换机
        rabbitTemplate.setExchange(env.getProperty("order.mq.exchange.name"));
        //设置routingkey
        rabbitTemplate.setRoutingKey(env.getProperty("order.mq.routing.key"));
        Message message = MessageBuilder.withBody(order).setContentType(MessageProperties.CONTENT_TYPE_JSON).setContentEncoding("UTF-8").setMessageId(UUID.randomUUID().toString()).build();
        rabbitTemplate.convertAndSend
        ("seckillEX",
        "seckill",message);
        //等待声明代码配置完毕再验证功能
        // Todo 
        return SysResult.ok();
    }
/**
 * 消息监听器(消费者)
 */
@Component
public class OrderListener implements ChannelAwareMessageListener {

    @Autowired
    private OrderService orderService;
    /**
     * 处理接收到的消息
     * @param message 消息体
     * @param channel 通道,确认消费用
     * @throws Exception
     */
    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        try{
            //下单,操作数据库
            orderService.order(obj.getString("userId"),obj.getString("goodsId"));
            //确认消费
            channel.basicAck(tag,true);
        }catch(Exception e){
            logger.error("消息监听确认机制发生异常:",e.fillInStackTrace());
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值