最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
基于Redis结合SpringBoot秒杀代码实例
时间:2022-06-29 10:42:08 编辑:袖梨 来源:一聚教程网
本篇文章小编给大家分享一下基于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;
@SpringBootApplication
public class QuickbuyApplication {
public static void main(String[] args) {
SpringApplication.run(QuickbuyApplication.class, args);
}
}
3、在Controller层里定义秒杀接口
@RestController
public 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;
@Service
public 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" +
"endn" +
"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=8081 spring.redis.host=192.168.159.22 spring.redis.port=6379
6、演示秒杀效果
6.1 准备redis环境
我用的刚搭建的redis主从复制集群,一主二从
设置10个商品
6.2 启动项目
在浏览器访问http://loca**lhost:*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
先重新设置商品数量为10
启动上面的程序
再次进入Redis查看商品数量和秒杀成功的用户
可以看到,15个线程秒杀商品,最终成功的只有10个。
相关文章
- 三国志8重制版结为配偶作用介绍说明 11-01
- 三国志8重制版结为金兰作用介绍说明 11-01
- 三国志8重制版助阵触发条件及方法分享 11-01
- 三国志8重制版娶湘姬条件及作用说明 11-01
- 三国志8重制版娶莲姬条件及作用说明 11-01
- 荒野大镖客救赎亡灵宝藏猎人成就攻略 11-01






