千家信息网

如何基于Redis结合SpringBoot实现秒杀

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,这篇文章主要介绍如何基于Redis结合SpringBoot实现秒杀,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1、构建SpringBoot项目搭建名为quickbuy的spr
千家信息网最后更新 2026年11月04日如何基于Redis结合SpringBoot实现秒杀

这篇文章主要介绍如何基于Redis结合SpringBoot实现秒杀,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

1、构建SpringBoot项目

搭建名为quickbuy的springboot项目,相关的依赖包如下所示:

    4.0.0            org.springframework.boot        spring-boot-starter-parent        2.1.13.RELEASE                 com.baizhi    quickbuy    0.0.1-SNAPSHOT    quickbuy    Demo project for Spring Boot            1.8                            org.springframework.boot            spring-boot-starter-data-redis                            org.springframework.boot            spring-boot-starter-web                            org.springframework.boot            spring-boot-starter-test            test                            org.apache.httpcomponents            httpclient            4.5.5                            org.apache.httpcomponents            httpcore            4.4.10                                                    org.springframework.boot                spring-boot-maven-plugin                        

引入了Redis、HttpClient等依赖包。
项目结构

2、启动类

package com.baizhi;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class QuickbuyApplication {    public static void main(String[] args) {        SpringApplication.run(QuickbuyApplication.class, args);    }}

3、在Controller层里定义秒杀接口

@RestControllerpublic class QuickBuyController {    @Autowired    private SellService sellService;    @RequestMapping("/quickBuy/{item}/{owner}")    public String quickbuy(@PathVariable String item,@PathVariable String owner){        String result=sellService.quickBuy(item,owner);        if(!result.equals("0")){            return owner+"success";        }else{            return owner+"fail";        }    }}

  通过@RequestMapping注解们可以把"/quickBuy/{item}/{owner}"格式的url映射到quickBuy方法上。
   quickBuy是秒杀接口,该接口包含的两个参数是item和owner,分别表示待秒杀的商品名和发起秒杀请求的用户。这两个参数均被@PathVariable注解修饰,说明来自于url里的{item}和{owner}部分。
  在这个quickBuy秒杀接口中调用了SellService类里的quickBuy方法实现了秒杀功能,并根据SellService类quickBuy方法返回的结果,向外部返回"秒杀成功"或"秒杀失败"的字符串语句。

4、在Service层里通过lua脚本实现秒杀效果

package com.baizhi.service;import org.springframework.data.redis.connection.RedisConnection;import org.springframework.data.redis.connection.ReturnType;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.script.DefaultRedisScript;import org.springframework.stereotype.Service;import javax.annotation.Resource;@Servicepublic class SellService {    @Resource    private RedisTemplate redisTemplate;    public String quickBuy(String item, String owner) {        //用lua脚本实现秒杀        String luaScript="local owner=ARGV[1]\n" +                "local item=KEYS[1] \n" +                "local leftNum=tonumber(redis.call('get',item)) \n" +                "if(leftNum>=1)\n" +                "then redis.call('decrby',item,1)\n" +                "redis.call('rpush','ownerList',owner)\n" +                "return 1 \n" +                "else \n" +                "return 0 \n" +                "end\n" +                "\n";        String key=item;        String args=owner;        DefaultRedisScript redisScript=new DefaultRedisScript();        redisScript.setScriptText(luaScript);        //调用lua脚本,请注意传入的参数        Object luaResult=redisTemplate.execute((RedisConnection connection)->connection.eval(           redisScript.getScriptAsString().getBytes(),           ReturnType.INTEGER,           1,           key.getBytes(),           args.getBytes()        ));        //根据lua脚本的执行情况返回结果        return luaResult.toString();    }}

对lua脚本的解释如下:

   通过ARGV[1]参数传入发起秒杀请求的用户,用KEYS[1]参数传入待秒杀的商品。通过get item命令判断item商品在Redis里还有多少库存。
  if语句中判定剩余库存大于等于1,就会先执行decrby命令把库存数减1,随后调用第6行的rpush命令,在ownerList里记录当前秒杀成功的用户,并通过return 1表示秒杀成功。如果判断库存数已经小于1,那么return 0表示秒杀失败。
  其中将lua脚本赋予redisScript对象,并通过redisTemplate.execute方法执行lua脚本。

在调用redisTemplate.execute方法执行lua脚本时请注意以下三点:

  • 需要以butes方式传入脚本

  • 需要指定返回类型

  • 传入该lua脚本所包含的KEYS类型参数的个数是1.

  • 传入的KEYS和ARGV类型的参数需要转换成bytes类型

5、配置redis连接参数

application.properties

server.port=8081spring.redis.host=192.168.159.22spring.redis.port=6379

6、演示秒杀效果

6.1 准备redis环境

我用的刚搭建的redis主从复制集群,一主二从

设置10个商品

6.2 启动项目

  在浏览器访问http://localhost:8081/quickBuy/Computer/abc,测试秒杀接口,该url传入的商品名是"Computer",需要和上面设置的商品名称一致,传入的发起秒杀请求的客户端名字为abc。输入该url后,能看到表示秒杀成功的如下输出。


进入redis查看


发现商品数量变成了9,且能看到秒杀成功的用户列表。

6.3 多线程形式发起秒杀请求

QuickBuyClients.java

package com.baizhi.client;import org.apache.http.HttpEntity;import org.apache.http.client.ClientProtocolException;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClientBuilder;import org.apache.http.util.EntityUtils;public class QuickBuyClients extends Thread{    @Override    public void run() {        QuickBuyUtil.quickBuy();    }    public static void main(String[] args) {        //开启15个线程,线程数多余秒杀商品数        for(int cnt=0;cnt<15;cnt++){            new QuickBuyClients().start();        }    }}//封装秒杀方法的工具类class QuickBuyUtil{    //在这个方法里,用HttpGet对象发起秒杀请求    public static void quickBuy(){        String user=Thread.currentThread().getName();        CloseableHttpClient httpClient= HttpClientBuilder.create().build();        //创建秒杀Get类型的url请求        HttpGet httpGet=new HttpGet("http://localhost:8081/quickBuy/Computer/"+user);        //得到响应结果        CloseableHttpResponse res=null;        try{            res=httpClient.execute(httpGet);            HttpEntity responseEntity=res.getEntity();            if(res.getStatusLine().equals("200")&&responseEntity!=null){                System.out.println("秒杀结果:"+ EntityUtils.toString(responseEntity));            }        }catch (ClientProtocolException e){            e.printStackTrace();        }catch (Exception e){            e.printStackTrace();        }finally {            try{                //回收http连接资源                if(httpClient!=null){                    httpClient.close();                }                if(res!=null){                    res.close();                }            }catch (Exception e){                e.printStackTrace();            }        }    }}

先重新设置商品数量为10

启动上面的程序
再次进入Redis查看商品数量和秒杀成功的用户

可以看到,15个线程秒杀商品,最终成功的只有10个。

以上是"如何基于Redis结合SpringBoot实现秒杀"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!

商品 脚本 参数 成功 方法 接口 用户 类型 库存 线程 结果 项目 命令 数量 两个 内容 对象 效果 注解 篇文章 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 喔噻互联网科技有限公司 中国互联网科技工作委员会毛军 互联网为科技 互联网巨头科技公司 关于新基建和互联网科技 沃里互联网科技 广州紫鲸互联网科技 互联网科技的未来发展 甘肃拓世互联网科技有限公司 农村开互联网科技讲堂 现代科技和互联网有关系吗 西藏七维空间互联网科技有限公司 广州慧亚互联网科技怎么样 西安小鹰速贷互联网科技有限公司 南博望互联网科技有限公司 福州德业互联网科技 版纳互联网科技选哪家 艺电能源互联网科技有限公司招聘 银川新华互联网科技学校是国营吗 西安左小互联网科技有限公司 互联网下的科技发展 科技伦理 互联网公司 开启互联网科技时代小说 互联网教育科技公司vipkid 昭通互联网科技选哪家 佛山市拉法互联网科技有限公司 朱啸虎曾投资哪些互联网科技企业 玉溪新华互联网科技怎么选 安徽九吞吴互联网科技有限公司 广东猫王互联网科技有限公司电话
0