IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> Redis(10) -- 不考虑并发的秒杀案例实现 -> 正文阅读

[大数据]Redis(10) -- 不考虑并发的秒杀案例实现

Redis6

9.3)Redis的事务秒杀案例

9.3.1)解决计数器和人员记录的事务操作

秒杀主要包括两个操作:1)商品库存 - 1 2)秒杀成功的该用户加到秒杀成功者清单里

?9.3.2)不考虑并发的秒杀案例实现

新建工程 Seckill ,这是一个WEB工程

创建页面:index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
 ? ?pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>iPhone 13 Pro !!!  1元秒杀!!!
</h1>
?
<form id="msform" action="${pageContext.request.contextPath}/doseckill" enctype="application/x-www-form-urlencoded">
    <%--固定商品id设置为0101--%>
    <input type="hidden" id="prodid" name="prodid" value="0101">
    <input type="button" ?id="miaosha_btn" name="seckill_btn" value="秒杀点我"/>
</form>
?
</body>
<script ?type="text/javascript" src="${pageContext.request.contextPath}/script/jquery/jquery-3.1.0.js"></script>
<script ?type="text/javascript">
$(function(){
    $("#miaosha_btn").click(function(){
        var url=$("#msform").attr("action");
     ? ? $.post(url,$("#msform").serialize(),function(data){
 ? ?        if(data=="false"){
 ?              alert("抢光了" );
 ?              $("#miaosha_btn").attr("disabled",true);
 ?          }
        } );
    })
})
</script>
</html>

创建 SecKillServlet,页面按钮点击秒杀调用doPost()方法

public class SecKillServlet extends HttpServlet {
 ? ?private static final long serialVersionUID = 1L;
?
 ? ?public SecKillServlet() {
 ? ? ? ?super();
 ?  }
?
 ? ?@Override
 ? ?protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 ?      // 通过随机数生成用户id
 ? ? ? ?String userid = new Random().nextInt(50000) + "";
 ? ? ? ?// 接收调用的商品id
 ? ? ? ?String prodid = request.getParameter("prodid");
 ? ? ? ?// 调用秒杀方法
 ? ? ? ?boolean isSuccess = SecKill_redis.doSecKill(userid, prodid);
 ? ? ? ?// 根据秒杀的返回结果返回相应信息
 ? ? ? ?response.getWriter().print(isSuccess);
 ?  }
}

创建 SecKill_redis.java,秒杀主方法,秒杀的全流程在这里开发

public class SecKill_redis {
?
 ? ?public static void main(String[] args) {
 ? ? ? ?Jedis jedis = new Jedis("82.157.183.197", 11079);
 ? ? ? ?System.out.println(jedis.ping());
 ? ? ? ?jedis.close();
 ?  }
?
 ? ?//秒杀主方法--全过程
 ? ?public static boolean doSecKill(String uid, String prodid) throws IOException {
 ? ? ? ?//步骤1 根据入参用户ID-uid和商品ID-prodid 进行非空判断
 ? ? ? ?if (uid == null || prodid == null) {
 ? ? ? ? ? ?return false;
 ? ? ?  }
?
 ? ? ? ?//步骤2 连接redis
 ? ? ? ?Jedis jedis = new Jedis("127.0.0.1", 11079);
?
 ? ? ? ?//步骤3 拼接key
 ? ? ? ?// 3.1 库存key
 ? ? ? ?String kcKey = "sk:" + prodid + ":qt";
 ? ? ? ?// 3.2 秒杀成功的用户key
 ? ? ? ?String userKey = "sk:" + prodid + ":user";
?
 ? ? ? ?// 步骤4 获取库存,如果库存null,秒杀还没有开始
 ? ? ? ?String kc = jedis.get(kcKey);
 ? ? ? ?if (kc == null) {
 ? ? ? ? ? ?System.out.println("秒杀还没有开始,请等待");
 ? ? ? ? ? ?jedis.close();
 ? ? ? ? ? ?return false;
 ? ? ?  }
?
 ? ? ? ?// 步骤5 判断用户是否重复秒杀操作
 ? ? ? ?// 判断set集合中的用户信息,因为不能存在重复的用户【不能重复秒杀】所以使用Set存储用户信息
 ? ? ? ?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 秒杀的过程
 ? ? ? ?//7.1 库存-1
 ? ? ? ?jedis.decr(kcKey);
 ? ? ? ?//7.2 把秒杀成功用户添加清单里面
 ? ? ? ?jedis.sadd(userKey, uid);
?
 ? ? ? ?System.out.println("秒杀成功了..");
 ? ? ? ?jedis.close();
 ? ? ? ?return true;
 ?  }
}

测试:启动Tomcat工程

浏览器访问:http://localhost:8080/Seckill/

点击 “秒杀按钮” ,此时还未向 Redis 中添加 商品信息,效果如下图:

?向Redis中加入商品信息,命令如下:【添加了5个商品】

127.0.0.1:11079> flushdb
OK
127.0.0.1:11079> keys *
(empty array)
127.0.0.1:11079> set sk:0101:qt 5
OK
127.0.0.1:11079> keys *
1) "sk:0101:qt"

刷新页面后再次点击秒杀按钮”,效果如下图:

?弹框不再弹出,且后台提示 —— 秒杀成功了..

在Redis中查看相关商品和用户信息:

127.0.0.1:11079> get sk:0101:qt
"4"
127.0.0.1:11079> smembers sk:0101:user
1) "452"

发现商品数量已减少1,用户列表新增了秒杀成功的用户

再次点击秒杀按钮”,直到第六次,效果如下图:

?弹框再次弹出,且后台提示 —— 秒杀已经结束了

在Redis中查看相关商品和用户信息:

127.0.0.1:11079> get sk:0101:qt
"0"
127.0.0.1:11079> smembers sk:0101:user
1) "452"
2) "16928"
3) "27602"
4) "41023"
5) "41347"

发现商品信息已经为0,同时用户列表中已经有了5个秒杀成功的用户

并发测试:

在Linux系统中安装:

yum install httpd-tools

通过ab进行测试

在根目录新建 postfile 文件,内容如下:

prodid=0101&

在根目录执行下列命令,执行并发测试

ab -n 1000 -c 100  -p ~/postfile -T application/x-www-form-urlencoded http://172.19.83.237:8080/Seckill/doseckill

【1000个请求、100个并发,调用172.19.83.237(个人主机)上的秒杀方法】

输出:

存在问题:?

  • 已经秒杀结束了,但还存在秒杀成功的情况

  • 【超卖问题】Redis 中的商品信息为 -3,不能出现商品为负数的情况

  • 【连接超时问题】Redis 无法同时处理过多的请求,不能处理的请求需要等待,等待时间过长会报连接超时错误

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 17:49:30  更:2022-04-18 17:50:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:30:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码