SpringBoot整合Redis 进阶篇 高并发秒杀案例 (有源码)


目录

1、成品展示

2、简介

3、安装ab模拟并发工具

4、秒杀案例介绍

如果对redis操作不熟悉的请点击下面的链接学习:

SpringBoot整合Redis 详解  快速入门篇 (有源码)

如果对docker操作不熟悉的请点击下面的链接学习:

CentOS7服务器搭建SpringBoot项目 详解 (基本操作)

1、成品展示

2、简介

本次介绍的是如何利用Redis实现高并发秒杀商品,利用Redis的事务乐观锁实现高并发秒杀商品,但是这里面还是存在一些问题就是存在少买的问题 但是问题不大,可以利用lua脚本解决 本次例子不做介绍。

本次例子为了方便演示,仅仅用了redis没有用到关系型数据库,这个你可以自行设计,当秒杀结束后,再将数据保存到关系型数据库中。

3、安装ab模拟并发工具

采用Xshell工具连接到服务器的控制台。

  • 输入 yum install httpd-tools 安装ab模拟并发工具

  • 再输入 y  确认安装

操作如下图:

ab使用介绍

并发测试代码如下:

ab -k -n 1000 -c 50 http://106.12.192.182/placeorder?commodity=101

为了方便传递数据我直接用get方式传递数据了。

其中 

  • -k 代表启用HTTP KeepAlive功能,即在一个HTTP会话中执行多个请求。

  • -n 代表请求数

  • -c 代表并发数

4、秒杀案例介绍

利用IDEA创建项目并导入依赖,操作如下图:

配置Redis:

分别配置Redis的IP地址与登录密码,在application.yml中添加以下代码:

spring:
    #配置redis
    redis:
      #配置redis连接地址
      host: 106.12.192.182
      #配置redis连接密码
      password: 123456

host即是服务器安装redisIP地址password就是redis的登录密码。

秒杀案例主要代码:

@ResponseBody
@GetMapping("/placeorder")
public boolean getUser(HttpServletRequest request) {


    String commodity = request.getParameter("commodity");//获取商品编号
    System.out.println(commodity);
    if (commodity==null||!"101 102 103".contains(commodity)) return false;//商品号不存在


    long orderNum = System.currentTimeMillis();//获取当前的时间戳当做订单号


    //判断该订单号是否已经成功下单
    boolean temp = stringRedisTemplate.opsForSet().isMember("orderNum",orderNum+"");//如果订单号已经购买成功
    if (temp) return true;


    stringRedisTemplate.setEnableTransactionSupport(true);//开启事务的支持
    stringRedisTemplate.watch("num"+commodity);//watch某个key,当该key被其它客户端改变时,则会中断当前的操作


    String numTemp = stringRedisTemplate.opsForValue().get("num"+commodity);
    if(numTemp==null) return false;
    long num = Long.valueOf(numTemp);//获取当前商品的数量
    if (num<=0){//检查当前商品的数量
       stringRedisTemplate.opsForList().leftPush("state","订单号="+orderNum+"----商品编号="+commodity+"----秒杀已结束");
       return false;
    }
    stringRedisTemplate.multi();//事务
    stringRedisTemplate.boundValueOps("num"+commodity).decrement(1);//下单成功 商品数量减1
    stringRedisTemplate.opsForSet().add("orderNum",orderNum+"");
    List<Object> exec = stringRedisTemplate.exec();//执行事务
    if (exec==null||exec.size()==0){
       stringRedisTemplate.opsForList().leftPush("state","订单号="+orderNum+"----商品编号="+commodity+"----秒杀失败");
       return false;
    }else{
       stringRedisTemplate.opsForList().leftPush("state","订单号="+orderNum+"----商品编号="+commodity+"----秒杀成功");
       return true;//成功秒杀商品
    }
}

介绍:

演示代码的大致处理流程是 获取秒杀的商品信息,开启事务 监控事务 获取商品的库存数量 判断库存是否充足 充足就将库存减1 提交事务,提交事务后判断是否执行成功。

使用StringRedisTemplate类RedisTemplate类操作缓存。

其中最重要的就是以下4行代码:

开启事务的支持:

stringRedisTemplate.setEnableTransactionSupport(true);//开启事务的支持

监控事务:

注:这一行代码是最重要的,就是乐观锁的体现。

stringRedisTemplate.watch("num"+commodity);//watch某个key,当该key被其它客户端改变时,则会中断当前的操作

减商品库存:

stringRedisTemplate.boundValueOps("num"+commodity).decrement(1);//下单成功 商品数量减1

执行事务:

注:返回值就是执行的内容,如果返回为null 或 数据量为0 则表明没有执行成功。

List<Object> exec = stringRedisTemplate.exec();//执行事务

回复获取资源

关注后回复 秒杀案例 

获取本次秒杀案例的源文件

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值