redis秒杀案例

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: redis秒杀案例

redis秒杀案例:


1.连接池:


public class JedisPoolUtil {
  private static volatile JedisPool jedisPool = null;
  private JedisPoolUtil() {
  }
  public static JedisPool getJedisPoolInstance() {
    if (null == jedisPool) {
      synchronized (JedisPoolUtil.class) {
        if (null == jedisPool) {
          JedisPoolConfig poolConfig = new JedisPoolConfig();
          poolConfig.setMaxTotal(200);
          poolConfig.setMaxIdle(32);
          poolConfig.setMaxWaitMillis(100*1000);
          poolConfig.setBlockWhenExhausted(true);
          poolConfig.setTestOnBorrow(true);  // ping  PONG
          jedisPool = new JedisPool(poolConfig, "192.168.44.168", 6379, 60000 );
        }
      }
    }
    return jedisPool;
  }
  public static void release(JedisPool jedisPool, Jedis jedis) {
    if (null != jedis) {
      jedisPool.returnResource(jedis);
    }
  }
}


2.秒杀过程:


public class SecKill_redis {
  public static void main(String[] args) {
    Jedis jedis =new Jedis("192.168.44.168",6379);
    System.out.println(jedis.ping());
    jedis.close();
  }
  //秒杀过程
  public static boolean doSecKill(String uid,String prodid) throws IOException {
    //1 uid和prodid非空判断
    if(uid == null || prodid == null) {
      return false;
    }
    //2 连接redis
    //Jedis jedis = new Jedis("192.168.44.168",6379);
    //通过连接池得到jedis对象
    JedisPool jedisPoolInstance = JedisPoolUtil.getJedisPoolInstance();
    Jedis jedis = jedisPoolInstance.getResource();
    //3 拼接key
    // 3.1 库存key
    String kcKey = "sk:"+prodid+":qt";
    // 3.2 秒杀成功用户key
    String userKey = "sk:"+prodid+":user";
    //监视库存
    jedis.watch(kcKey);
    //4 获取库存,如果库存null,秒杀还没有开始
    String kc = jedis.get(kcKey);
    if(kc == null) {
      System.out.println("秒杀还没有开始,请等待");
      jedis.close();
      return false;
    }
    // 5 判断用户是否重复秒杀操作
    if(jedis.sismember(userKey, uid)) {
      System.out.println("已经秒杀成功了,不能重复秒杀");
      jedis.close();
      return false;
    }
    //6 判断如果商品数量,库存数量小于1,秒杀结束
    if(Integer.parseInt(kc)<=0) {
      System.out.println("秒杀已经结束了");
      jedis.close();
      return false;
    }
    //7 秒杀过程
    //使用事务
    Transaction multi = jedis.multi();
    //组队操作
    multi.decr(kcKey);
    multi.sadd(userKey,uid);
    //执行
    List<Object> results = multi.exec();
    if(results == null || results.size()==0) {
      System.out.println("秒杀失败了....");
      jedis.close();
      return false;
    }
    //7.1 库存-1
    //jedis.decr(kcKey);
    //7.2 把秒杀成功用户添加清单里面
    //jedis.sadd(userKey,uid);
    System.out.println("秒杀成功了..");
    jedis.close();
    return true;
  }
}


3.脚本


public class SecKill_redisByScript {
  private static final  org.slf4j.Logger logger =LoggerFactory.getLogger(SecKill_redisByScript.class) ;
  public static void main(String[] args) {
    JedisPool jedispool =  JedisPoolUtil.getJedisPoolInstance();
    Jedis jedis=jedispool.getResource();
    System.out.println(jedis.ping());
    Set<HostAndPort> set=new HashSet<HostAndPort>();
  //  doSecKill("201","sk:0101");
  }
  static String secKillScript ="local userid=KEYS[1];\r\n" + 
      "local prodid=KEYS[2];\r\n" + 
      "local qtkey='sk:'..prodid..\":qt\";\r\n" + 
      "local usersKey='sk:'..prodid..\":usr\";\r\n" + 
      "local userExists=redis.call(\"sismember\",usersKey,userid);\r\n" + 
      "if tonumber(userExists)==1 then \r\n" + 
      "   return 2;\r\n" + 
      "end\r\n" + 
      "local num= redis.call(\"get\" ,qtkey);\r\n" + 
      "if tonumber(num)<=0 then \r\n" + 
      "   return 0;\r\n" + 
      "else \r\n" + 
      "   redis.call(\"decr\",qtkey);\r\n" + 
      "   redis.call(\"sadd\",usersKey,userid);\r\n" + 
      "end\r\n" + 
      "return 1" ;
  static String secKillScript2 = 
      "local userExists=redis.call(\"sismember\",\"{sk}:0101:usr\",userid);\r\n" +
      " return 1";
  public static boolean doSecKill(String uid,String prodid) throws IOException {
    JedisPool jedispool =  JedisPoolUtil.getJedisPoolInstance();
    Jedis jedis=jedispool.getResource();
     //String sha1=  .secKillScript;
    String sha1=  jedis.scriptLoad(secKillScript);
    Object result= jedis.evalsha(sha1, 2, uid,prodid);
      String reString=String.valueOf(result);
    if ("0".equals( reString )  ) {
      System.err.println("已抢空!!");
    }else if("1".equals( reString )  )  {
      System.out.println("抢购成功!!!!");
    }else if("2".equals( reString )  )  {
      System.err.println("该用户已抢过!!");
    }else{
      System.err.println("抢购异常!!");
    }
    jedis.close();
    return true;
  }
}


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3月前
|
JSON NoSQL Redis
|
4月前
|
缓存 NoSQL Java
Redis7的10大应用场景和案例解析
你在项目中使用 Redis 实现了什么应用场景,欢迎一起跟 V 哥讨论。同时也做个小调查,朋多少兄弟是需要了解 Redis 核心源码的,人多的话,下一篇 V 哥写 Redis7的源码分析,人少的话就算了,感谢。
114 0
|
4月前
|
存储 监控 NoSQL
【Redis技术专区】「优化案例」谈谈使用Redis慢查询日志以及Redis慢查询分析指南
【Redis技术专区】「优化案例」谈谈使用Redis慢查询日志以及Redis慢查询分析指南
132 0
|
4月前
|
缓存 NoSQL 前端开发
【Redis技术专区】「实战案例」谈谈使用Redis缓存时高效的批量删除的几种方案
【Redis技术专区】「实战案例」谈谈使用Redis缓存时高效的批量删除的几种方案
119 0
|
4月前
|
NoSQL Java 数据库
优惠券秒杀案例 - CAS、Redis+Lua脚本解决高并发并行
优惠券秒杀案例 - CAS、Redis+Lua脚本解决高并发并行
248 0
|
存储 缓存 NoSQL
案例01-修改数据redis没有同步更新
修改数据redis没有同步更新
107 0
|
4月前
|
存储 NoSQL 关系型数据库
Redis系列-8.Redis案例实战之Bitmap、Hyperloglog、GEO(下)
Redis系列-8.Redis案例实战之Bitmap、Hyperloglog、GEO
57 0
|
4月前
|
存储 NoSQL 算法
Redis系列-8.Redis案例实战之Bitmap、Hyperloglog、GEO(上)
Redis系列-8.Redis案例实战之Bitmap、Hyperloglog、GEO
74 0
|
10月前
|
消息中间件 缓存 NoSQL
阿里云国际站代理商:Redis实现分布式配置管理的方法与应用案例
@luotuoemo飞机@TG阿里云国际站代理商:Redis实现分布式配置管理的方法与应用案例,为了实现高可用和负载均衡,可以将Redis部署成哨兵集群或集群模式。哨兵负责监控主从节点的状态,发现故障时自动进行故障转移。集群模式可以提高系统的可扩展性,通过添加更多的从节点来分摊负载压力。
|
11月前
24Redis - 事务测试案例
24Redis - 事务测试案例
46 0