zoukankan      html  css  js  c++  java
  • (转)秒杀系统中如何动态生成下单随机URL

    秒杀系统中通常会避免用户之间访问下单页面的URL(避免使用爬虫来造成不公平)。所有需要将URL动态化,即使秒杀系统的开发人员也无法在知晓在秒杀开始时的URL。解决办法是在获取秒杀URL的接口中,返回一个服务器端生成的随机数,并在下单URL中传递该参数完成下单。

    首先构造一个获取下单URL的modle

    public class Exposer {
    
    
        //加密措施
        private String md5;
    
        //其中必要字段,如是否开启秒杀,时间等省
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    获取秒杀URL的conntroller:

       @RequestMapping(value = "/{goodsId}/getUrl")
        public Exposer exposer(@PathVariable("goodsId") Long seckillGoodsId)
        {
        //goodsId表示是什么商品,然后根据该商品的数据库依次获得尚未被秒杀的每个商品的唯一ID,然后根据商品的唯一ID来生成唯一的秒杀URL
        seckillGoodsId为某个商品的唯一id
    其中这一步可以省,之间将goodsId表示的传递给exportSeckillUrl也可以完成
        //异常判断省掉,返回上述的model对象。即包含md5的对象
                Exposer result =seckillService.exportSeckillUrl(seckillGoodsId);
                return result;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    Service的方法实现:

      //加入一个混淆字符串(秒杀接口)的salt,为了我避免用户猜出我们的md5值,值任意给,越复杂越好
    private final String salt="12sadasadsafafsafs。/。,";
    
    public Exposer exportSeckillUrl(long seckillGoodsId) {
          //首页根据该seckillGoodsId判断商品是否还存在。
          //如果不存在则表示已经被秒杀
          String md5 = getMD5(seckillGoodsId);
          return  new Exposer(md5);
    }
    
      private String getMD5(long seckillGoodsId)
        {
            //结合秒杀的商品id与混淆字符串生成通过md5加密
            String base=seckillGoodsId+"/"+salt;
            String md5= DigestUtils.md5DigestAsHex(base.getBytes());
            return md5;
        }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    用户在获取获取到下单URL的时候,当秒杀开启后则会得到一个md5值。通过该md5值来完成下单具体的秒杀交易:

    具体执行秒杀操作的接口

     @RequestMapping(value = "/{seckillGoodsId}/{md5}/execution")
        public Boolean execution(@PathVariable("seckillGoodsId") Long seckillGoodsId,@PathVariable("md5") String md5){
                Boolean result = seckillService.executionSeckillId(seckillId,md5);
                //executionSeckillId的操作是强事务,操作为减库存+增加购买明细,最终返回是否秒杀成功,秒杀成功的商品消息等。这里省,只返回是否接口合理的信息。
                return  result;
        }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Service 执行秒杀的过程:

     public Boolean executionSeckillId(long seckillID,String md5){
          if(md5==null||!md5.equals(getMD5(seckillID))){
             //表示接口错误,不会执行秒杀操作
             return false;
          }
          //接口正确,排队执行秒杀操作。减库存+增加购买明细等信息,这里只返回false
          return  true;
        }
    }
  • 相关阅读:
    什么叫线程安全?servlet 是线程安全吗?
    SynchronizedMap 和 ConcurrentHashMap 有什么区别?
    CopyOnWriteArrayList 可以用于什么应用场景?
    乐观锁和悲观锁的理解及如何实现,有哪些实现方式?
    当一个线程进入某个对象的一个 synchronized 的实例方 法后,其它线程是否可进入此对象的其它方法?
    一个线程运行时发生异常会怎样?
    用 Java 实现阻塞队列 ?
    在 java 中 wait 和 sleep 方法的不同?
    为什么代码会重排序?
    volatile 有什么用?能否用一句话说明下 volatile 的应用场景?
  • 原文地址:https://www.cnblogs.com/panxuejun/p/8427459.html
Copyright © 2011-2022 走看看