使用Redis中间件解决商品秒杀活动中出现的超卖问题(使用Java多线程模拟高并发环境)

news/2024/11/17 3:37:04/

说明:正文中对代码的解释性文字较少,因为代码中有详细的注释。

一、引入Jedis依赖

可以新建Spring或Maven工程,在pom文件中引入Jedis依赖:

 <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.9.0</version></dependency>

二、Jedis工具类

JedisUtil.java

package com.jake.mallseckill.utils;import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;public class JedisUtil {// Redis服务器IPprivate static final String ADDR = "Redis_IP";// Redis的端口号private static final int PORT = 6379;// 在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;private static final boolean TEST_ON_BORROW = true;// 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值是8。private static final int MAX_IDLE = 200;private static JedisPool jedisPool = null;/*** 初始化Jedis连接池*/static {try {JedisPoolConfig config = new JedisPoolConfig();config.setMaxIdle(MAX_IDLE);config.setTestOnBorrow(TEST_ON_BORROW);jedisPool = new JedisPool(config, ADDR, PORT);} catch (Exception e) {e.printStackTrace();}}/*** 获取Jedis实例** @return*/public synchronized static Jedis getJedis() {try {if (jedisPool != null) {Jedis resource = jedisPool.getResource();return resource;} else {return null;}} catch (Exception e) {e.printStackTrace();return null;}}/*** 释放Jedis资源** @param jedis*/public static void returnResource(final Jedis jedis) {if (jedis != null) {// 注意这里不是关闭连接,在JedisPool模式下,Jedis会被归还给资源池。jedis.close();// 被废弃的方法,使用close即可。
//            jedisPool.returnResource(jedis);}}}

三、秒杀测试类(代码模拟多用户+高并发)

RedisSecKiller.java

package com.jake.mallseckill;import com.jake.mallseckill.utils.JedisUtil;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class RedisSecKiller {// 模拟用户抢购最大并发数private static final int N_THREADS = 5;// jedis通过watch方法监控WATCH_KEY,一旦发生改变,事务将失败。public static final String WATCH_KEY = "Goods";// 商品总数private static final int GOODS_NUM = 10;// 用户数量private static final int USER_NUM = 100;public static void main(String[] args) {// 创建线程池,模拟N_THREADS位用户同时抢购的过程。ExecutorService executorService = Executors.newFixedThreadPool(N_THREADS);Jedis jedis = JedisUtil.getJedis();// 设置商品总数为10jedis.set(WATCH_KEY, String.valueOf(GOODS_NUM));jedis.close();// 模拟USER_NUM位用户在抢购商品for (int i = 0; i < USER_NUM; i++) {executorService.execute(new JedisRunnable(UUID.randomUUID().toString()));
//            System.out.println("==============循环分割线===============");}executorService.shutdown();}}class JedisRunnable implements Runnable {private Jedis jedis = JedisUtil.getJedis();private String userId;public JedisRunnable(String userId) {this.userId = userId;}@Overridepublic void run() {try {// 事务状态,如果监控的key没有发生改变,那么应该返回OK,事务也可以正常执行。jedis.watch(RedisSecKiller.WATCH_KEY);// 获取剩余商品数int leftGoodsNum = Integer.valueOf(jedis.get(RedisSecKiller.WATCH_KEY));// 当剩余商品数大于0时,才进行剩余商品数减1的事务操作。if (leftGoodsNum > 0) {// 开启jedis事务Transaction tx = jedis.multi();// 方法一:在事务中对键Goods对应的值做减1操作,此时tx.exec()的返回值的第一个元素是Goods对应的当前值。tx.decrBy(RedisSecKiller.WATCH_KEY, 1);// 方法二:在事务中设置Goods的值为原值减1,此时tx.exec()的返回值的第一个元素是"OK"。
//                tx.set(RedisSecKiller.WATCH_KEY, String.valueOf(leftGoodsNum - 1));// 执行事务,得到返回值。List<Object> results = tx.exec();// leftGoodsNum比键Goods对应的值大1,因为事务中刚执行了减1操作。// 由此可知,在当前事务中,leftGoodsNum与Goods对应的值(真实剩余商品数量)并不同步。
//                System.out.println("剩余商品数量:" + leftGoodsNum);
//                System.out.println("真实剩余商品数量:" + results);// results为null或空时,表示并发情况下用户没能抢购到商品,秒杀失败。if (results == null || results.isEmpty()) {String failUserInfo = "fail---" + userId;// 此时无法通过results.get(0)获取真实剩余商品数量。String failMsg = "用户" + failUserInfo + ",抢购失败,剩余商品数量:"+ leftGoodsNum +",但此时无法获取真实剩余商品数量。";System.out.println(failMsg);// 将秒杀失败的用户信息存入Redis。jedis.setnx(failUserInfo, failMsg);} else { // 此时tx.exec()事务执行成功,会自动提交事务。for(Object succ : results) {String succUserInfo ="succ" + succ.toString() + "---" + userId;String succMsg= "用户" + succUserInfo + ",抢购成功,当前抢购成功人数:" +(10 - Integer.parseInt(results.get(0).toString())) +",真实剩余商品数量:" + Integer.parseInt(results.get(0).toString());System.out.println(succMsg);// 将秒杀成功的用户信息存入Redis。jedis.setnx(succUserInfo, succMsg);}}} else { // 此时库存为0,秒杀活动结束。String overUserInfo ="over---" + userId;String overMsg = "用户" + overUserInfo + ",商品被抢购完毕,剩余商品数量:" + leftGoodsNum;System.out.println(overMsg);// 将秒杀活动结束后还在访问秒杀系统的用户信息存入Redis。jedis.setnx(overUserInfo, overMsg);}} catch (Exception e) {e.printStackTrace();} finally {JedisUtil.returnResource(jedis);}}}

注:关于多线程部分代码的说明

传统的方式是使用new Thread来创建、运行(start)线程,但那样太低效了;使用定长线程池 + ExecutorService的execute方法来创建、运行线程,比前者高效得多。
参考博客:https://blog.csdn.net/daguanjia11/article/details/78857891

四、运行结果

4.1 Redis数据插入结果

进入RedisManager -> db0查看
在这里插入图片描述
在这里插入图片描述

4.2 IDEA控制台输出结果

用户fail---5dd952da-f9fc-4b5f-a8a8-ee9131fc8b51,抢购失败,剩余商品数量:10,但此时无法获取真实剩余商品数量。
用户fail---210dd063-2591-465c-9dba-52108ac7e788,抢购失败,剩余商品数量:10,但此时无法获取真实剩余商品数量。
用户fail---89f7671e-1e5e-4aa5-8696-c4d6aefa0aa1,抢购失败,剩余商品数量:10,但此时无法获取真实剩余商品数量。
用户fail---443c5586-5d29-482a-a8d2-48ddbdfe91ef,抢购失败,剩余商品数量:10,但此时无法获取真实剩余商品数量。
用户succ9---32785ae1-87e1-4af4-85ec-8e6753a346f3,抢购成功,当前抢购成功人数:1,真实剩余商品数量:9
用户succ8---58f2b976-c63d-4c80-aa7d-cb895ca434a8,抢购成功,当前抢购成功人数:2,真实剩余商品数量:8
用户fail---d1903f64-6f33-4ffd-87ed-76dd56d85292,抢购失败,剩余商品数量:9,但此时无法获取真实剩余商品数量。
用户fail---70cba697-dc9a-4e98-989a-ef0fe923ef40,抢购失败,剩余商品数量:9,但此时无法获取真实剩余商品数量。
用户succ7---8b0bcc5a-b4b9-4ac0-b718-116de8a16d3e,抢购成功,当前抢购成功人数:3,真实剩余商品数量:7
用户fail---14ff8673-d46e-437d-81b3-d274c6703664,抢购失败,剩余商品数量:7,但此时无法获取真实剩余商品数量。
用户fail---c40b5935-affa-449e-836c-a17c3a6b6f30,抢购失败,剩余商品数量:6,但此时无法获取真实剩余商品数量。
用户succ6---12c5a77f-114e-4bc3-90e7-b8896d1d1c67,抢购成功,当前抢购成功人数:4,真实剩余商品数量:6
用户succ5---9239c9d5-e26f-4da4-9f07-59e59c440465,抢购成功,当前抢购成功人数:5,真实剩余商品数量:5
用户succ4---778eeca9-05c6-42ed-b754-189fd4a02bf7,抢购成功,当前抢购成功人数:6,真实剩余商品数量:4
用户fail---9950c21f-a79a-4138-b2ee-f331aa0f291b,抢购失败,剩余商品数量:5,但此时无法获取真实剩余商品数量。
用户fail---a2cd7477-d762-49ff-96c0-0b9a30616e35,抢购失败,剩余商品数量:4,但此时无法获取真实剩余商品数量。
用户succ3---614ef53d-674b-42cc-ad85-02cd092a8898,抢购成功,当前抢购成功人数:7,真实剩余商品数量:3
用户fail---0322338f-72bf-483f-a844-670e644f18c6,抢购失败,剩余商品数量:3,但此时无法获取真实剩余商品数量。
用户succ2---c06620bc-3f9a-417b-970e-5338682763d0,抢购成功,当前抢购成功人数:8,真实剩余商品数量:2
用户fail---bcbee317-6110-489a-a60c-a8fc658d54d2,抢购失败,剩余商品数量:2,但此时无法获取真实剩余商品数量。
用户fail---52fbd3bc-62f1-4d87-9690-4b43f7312696,抢购失败,剩余商品数量:2,但此时无法获取真实剩余商品数量。
用户succ1---a2d33f13-0ead-480c-8e81-92fa90754d63,抢购成功,当前抢购成功人数:9,真实剩余商品数量:1
用户fail---31b030d6-b250-411e-945e-0cdac212d877,抢购失败,剩余商品数量:1,但此时无法获取真实剩余商品数量。
用户succ0---65e3b93b-66d7-48fc-a93c-c901cfbb10d8,抢购成功,当前抢购成功人数:10,真实剩余商品数量:0
用户over---f9fbc837-439d-44f2-9fd1-728406f45165,商品被抢购完毕,剩余商品数量:0
用户over---fd1fc73c-2986-42b0-a657-f928781c3896,商品被抢购完毕,剩余商品数量:0
用户over---e4e0821e-8056-4eca-bd79-312055b96f65,商品被抢购完毕,剩余商品数量:0
用户over---11dd3cf9-cb7b-424a-8f06-f9dfb344e8f9,商品被抢购完毕,剩余商品数量:0
用户over---227b7df9-5099-40af-8603-1f564c589f05,商品被抢购完毕,剩余商品数量:0
用户over---9d004a87-7901-475b-b85e-06928f863003,商品被抢购完毕,剩余商品数量:0
用户over---c6abeffe-fc03-4d32-850f-4da25caa7bc9,商品被抢购完毕,剩余商品数量:0
用户over---09973975-7a57-4165-94d3-c9f598ee520d,商品被抢购完毕,剩余商品数量:0
用户over---0b690ab6-4823-489d-96e9-73ba380718a9,商品被抢购完毕,剩余商品数量:0
用户over---16cad24a-3ddc-445b-a06d-087afa19a8e4,商品被抢购完毕,剩余商品数量:0
用户over---67680aba-79ee-42bd-b246-d1c6e4230f0f,商品被抢购完毕,剩余商品数量:0
用户over---17effafe-79f8-4e46-a52f-f2b8e2d7d765,商品被抢购完毕,剩余商品数量:0
用户over---582417d3-a6f0-4084-a6b4-98a8358db66c,商品被抢购完毕,剩余商品数量:0
用户over---d282f81b-e032-48a8-b800-7cdb3f89c995,商品被抢购完毕,剩余商品数量:0
用户over---5bd934aa-c476-4be7-92e9-be5781fd28e9,商品被抢购完毕,剩余商品数量:0
用户over---0e0d8083-db94-4385-8ffd-3b44a281e517,商品被抢购完毕,剩余商品数量:0
用户over---a1939cff-6295-40d1-bd05-e5c76aaecfd7,商品被抢购完毕,剩余商品数量:0
用户over---ddb2fba3-b897-4a7a-be02-beed7d8f712a,商品被抢购完毕,剩余商品数量:0
用户over---64f2d6ac-ee45-4cbf-816b-f7272d2bfad8,商品被抢购完毕,剩余商品数量:0
用户over---f6bbdefb-3d9d-44d1-a249-3768eb204642,商品被抢购完毕,剩余商品数量:0
用户over---ab628903-03d0-4445-a025-efc596c9dab3,商品被抢购完毕,剩余商品数量:0
用户over---9f3c569a-b03c-41d1-a5fd-d5f6af0fe2f2,商品被抢购完毕,剩余商品数量:0
用户over---263066ee-7245-47f8-9dcc-eb5cd11569e7,商品被抢购完毕,剩余商品数量:0
用户over---ec9273bf-2a0b-43cc-b5aa-7661413ea868,商品被抢购完毕,剩余商品数量:0
用户over---1d77263c-28d4-46bb-a2d6-cebebf436820,商品被抢购完毕,剩余商品数量:0
用户over---6430b3f2-3cfa-4091-a5aa-9bacd31e72fa,商品被抢购完毕,剩余商品数量:0
用户over---3bf43ac9-25c5-4ddd-b926-f04fe8b4b96a,商品被抢购完毕,剩余商品数量:0
用户over---1d84f400-3d52-4cb8-9e08-e1c6f711a8b9,商品被抢购完毕,剩余商品数量:0
用户over---c202a91d-248a-44c8-8f36-2ac4b1959455,商品被抢购完毕,剩余商品数量:0
用户over---7c719bb8-2878-48e4-8dac-69169e9e520b,商品被抢购完毕,剩余商品数量:0
用户over---fc7e0578-9945-47cb-b3ee-f14bd6b9b156,商品被抢购完毕,剩余商品数量:0
用户over---fff93805-7e11-4236-b627-45d9a83b7c74,商品被抢购完毕,剩余商品数量:0
用户over---7403da53-41ad-4ebc-ae8f-0eddd7b1c499,商品被抢购完毕,剩余商品数量:0
用户over---26fbad73-6437-459b-ae7c-b08c9b921c37,商品被抢购完毕,剩余商品数量:0
用户over---6da51bcb-f467-4b81-811a-56c21aab0f9f,商品被抢购完毕,剩余商品数量:0
用户over---751584d9-d6ff-4fe8-bcf9-915e8af77952,商品被抢购完毕,剩余商品数量:0
用户over---5882e880-6ddb-4af8-a4f9-848f61b1778c,商品被抢购完毕,剩余商品数量:0
用户over---d1d13e94-54ef-4fb2-a62d-131b8c2b4d73,商品被抢购完毕,剩余商品数量:0
用户over---bf76fcd9-2627-441b-999b-daf63da041c5,商品被抢购完毕,剩余商品数量:0
用户over---454d320b-d8cd-41ec-a445-0f538172fde2,商品被抢购完毕,剩余商品数量:0
用户over---821809c3-670e-4000-8641-d301dacbd882,商品被抢购完毕,剩余商品数量:0
用户over---75c4e707-1303-46bd-8b4f-951e166cd8f8,商品被抢购完毕,剩余商品数量:0
用户over---b9a2ff97-3ed8-4ddc-be84-0d95b7af09a1,商品被抢购完毕,剩余商品数量:0
用户over---ecf8e6d3-f74a-48e7-a883-5692385b8ffb,商品被抢购完毕,剩余商品数量:0
用户over---2abc320b-f5a2-4206-9c0b-a7bcdf1070a1,商品被抢购完毕,剩余商品数量:0
用户over---7859ad85-dfbd-4943-8f73-831f6502ab80,商品被抢购完毕,剩余商品数量:0
用户over---3979ec3e-d156-4d35-9b4e-9a6c76796ceb,商品被抢购完毕,剩余商品数量:0
用户over---c6e896f7-b753-4331-8099-87b63a52bdf9,商品被抢购完毕,剩余商品数量:0
用户over---a9231b36-0482-4787-bdeb-265bf31b8299,商品被抢购完毕,剩余商品数量:0
用户over---8f84dc27-f034-49fc-99e9-17258baebe1a,商品被抢购完毕,剩余商品数量:0
用户over---d1650ae9-d62a-4e8f-a793-27d0cdc85f44,商品被抢购完毕,剩余商品数量:0
用户over---34939be5-ad22-4256-99e2-418eb390b406,商品被抢购完毕,剩余商品数量:0
用户over---edbdf692-61b7-4d9c-ad2d-0dcfb2073655,商品被抢购完毕,剩余商品数量:0
用户over---f825d695-4648-46ed-9ad9-98b56ee64180,商品被抢购完毕,剩余商品数量:0
用户over---0849ce35-d0e9-40a5-8bfe-22f54c51de9a,商品被抢购完毕,剩余商品数量:0
用户over---72347a24-86a6-4fd9-b204-66a7ed66bca4,商品被抢购完毕,剩余商品数量:0
用户over---1b32bb40-2305-4b6c-b939-23ad6875010c,商品被抢购完毕,剩余商品数量:0
用户over---5b1d9653-1c7f-4bc8-bb5c-4f5309fecfce,商品被抢购完毕,剩余商品数量:0
用户over---54475f56-9090-436b-9595-154d105268c9,商品被抢购完毕,剩余商品数量:0
用户over---a979df12-1125-4661-b36a-f0ead8139f5c,商品被抢购完毕,剩余商品数量:0
用户over---20a1a07c-1001-4a2f-8a42-00385e3ed554,商品被抢购完毕,剩余商品数量:0
用户over---6218c4da-b2d0-49f7-a11e-3dc901d4b57b,商品被抢购完毕,剩余商品数量:0
用户over---3d3cff93-6fb3-4525-8dab-b52f03427482,商品被抢购完毕,剩余商品数量:0
用户over---9da859c2-07bd-45ac-904b-78af86357477,商品被抢购完毕,剩余商品数量:0
用户over---27752784-c57e-45ce-95c1-c8403ba24ab2,商品被抢购完毕,剩余商品数量:0
用户over---c35cacdc-eb8f-4408-bcd0-4a120e6eef2d,商品被抢购完毕,剩余商品数量:0
用户over---1088459a-b994-4e1d-863f-0b4b68e9cbe7,商品被抢购完毕,剩余商品数量:0
用户over---fb77ee5b-67b5-4331-a86c-d434958ea756,商品被抢购完毕,剩余商品数量:0
用户over---64fb3594-704e-42fc-bd5b-17f4e6ba1ec3,商品被抢购完毕,剩余商品数量:0
用户over---0fda1e7c-6a36-424d-b00a-11ddc82ae95f,商品被抢购完毕,剩余商品数量:0
用户over---e7f351bf-13a7-45c3-9c8c-0f8eb9e2614e,商品被抢购完毕,剩余商品数量:0
用户over---2c1e7263-d307-424c-84b9-6d544d7fbab4,商品被抢购完毕,剩余商品数量:0
用户over---c04de9e8-7ef3-41d4-a7c7-388d07e5e78f,商品被抢购完毕,剩余商品数量:0
用户over---5f1489c3-368d-4a5c-be2a-8a53ef6d275c,商品被抢购完毕,剩余商品数量:0
用户over---709d950b-ba09-4604-8d0c-caac487f449f,商品被抢购完毕,剩余商品数量:0
用户over---ef101b20-b723-445c-af0f-e54c0c9959b3,商品被抢购完毕,剩余商品数量:0

五、有趣的测试

5.1 用户数量小于商品数量,且等于最大并发数

将RedisSecKiller类中的USER_NUM从100改为5,因为此时N_THREADS仍然为5,最大并发数仍为5,即有5个用户同时在抢购10件商品。注意,只要最大并发数大于等于用户数量,就会造成所有用户同时抢购商品(高并发)的情况出现。
运行结果如下:

第一次运行main方法:

用户succ9---7391923d-574d-4fed-b3c1-97384aee812f,抢购成功,当前抢购成功人数:1,真实剩余商品数量:9
用户fail---19793ef1-cced-4ef4-bb80-54fdef84ef41,抢购失败,剩余商品数量:10,但此时无法获取真实剩余商品数量。
用户fail---9f003397-99fc-4291-ba04-04e26550698c,抢购失败,剩余商品数量:10,但此时无法获取真实剩余商品数量。
用户fail---106db002-612a-480d-b500-570dc227f203,抢购失败,剩余商品数量:10,但此时无法获取真实剩余商品数量。
用户fail---3767518c-2b91-4ef1-8494-2d2ac15472b2,抢购失败,剩余商品数量:10,但此时无法获取真实剩余商品数量。

第二次运行main方法:

用户succ9---37ae6462-7376-4818-aebf-ec6012353126,抢购成功,当前抢购成功人数:1,真实剩余商品数量:9
用户fail---afd13af2-2c46-442f-b759-7c90bbb784d4,抢购失败,剩余商品数量:10,但此时无法获取真实剩余商品数量。
用户fail---4533c4ec-bb52-4d43-b8fe-c44eafdaae18,抢购失败,剩余商品数量:9,但此时无法获取真实剩余商品数量。
用户succ7---eec22de0-4d55-4b64-bdbb-8864c4ddbd88,抢购成功,当前抢购成功人数:3,真实剩余商品数量:7
用户succ8---22be1def-7cf8-4751-808e-2fe18d9f055e,抢购成功,当前抢购成功人数:2,真实剩余商品数量:8

第三次运行main方法:

用户fail---6a0cf86f-264f-4686-8a80-d6a5a2ebf5c0,抢购失败,剩余商品数量:10,但此时无法获取真实剩余商品数量。
用户fail---2642bd04-15ab-4ce4-8646-58a61b6141c6,抢购失败,剩余商品数量:10,但此时无法获取真实剩余商品数量。
用户fail---7819bf7d-6958-4ae3-a708-2a16a1fa7396,抢购失败,剩余商品数量:10,但此时无法获取真实剩余商品数量。
用户succ9---7778f952-e965-4eee-862c-60df05107937,抢购成功,当前抢购成功人数:1,真实剩余商品数量:9
用户fail---3e293589-5e05-4e8a-988c-82d869291a7f,抢购失败,剩余商品数量:10,但此时无法获取真实剩余商品数量。

5.2 用户数量小于商品数量,且大于最大并发数

将N_THREADS从5改为3,此时有5名顾客抢购10件商品,但最多只有三名顾客在同一时刻抢购。运行结果:
第一次:

用户succ9---5859a79f-2045-4027-8800-a0cfd464d486,抢购成功,当前抢购成功人数:1,真实剩余商品数量:9
用户fail---76945d54-7b91-4eef-a03c-4d1c5bb5c963,抢购失败,剩余商品数量:9,但此时无法获取真实剩余商品数量。
用户fail---920bd322-4476-4c54-a031-481f29a7d5b2,抢购失败,剩余商品数量:8,但此时无法获取真实剩余商品数量。
用户succ8---ad4315b2-3637-406f-b7a3-be0b9cfd2a1e,抢购成功,当前抢购成功人数:2,真实剩余商品数量:8
用户succ7---d094667c-5cf9-431e-96bc-ab7902b4801b,抢购成功,当前抢购成功人数:3,真实剩余商品数量:7

第二次:

用户succ9---fadb56e5-2ba7-40b5-b572-e9e3e385cc5a,抢购成功,当前抢购成功人数:1,真实剩余商品数量:9
用户fail---247cf4f8-3ce8-4738-a315-5aa4ffe41472,抢购失败,剩余商品数量:10,但此时无法获取真实剩余商品数量。
用户fail---1bfd80d4-647d-4711-b9f4-5d6d0c64cbb9,抢购失败,剩余商品数量:10,但此时无法获取真实剩余商品数量。
用户succ8---e0f75396-46e7-4689-aa8e-578043df9d12,抢购成功,当前抢购成功人数:2,真实剩余商品数量:8
用户fail---54e87a3f-e992-42b9-bb6d-431d33217ed1,抢购失败,剩余商品数量:9,但此时无法获取真实剩余商品数量。

第三次:

用户fail---bd09d0d7-ac58-43c6-ba74-ce6afe436fc2,抢购失败,剩余商品数量:10,但此时无法获取真实剩余商品数量。
用户succ8---a79fb781-d3ae-4ca3-919e-d7cdec9f6227,抢购成功,当前抢购成功人数:2,真实剩余商品数量:8
用户succ9---8efeb302-9646-4f54-b2d3-bb24764cbc5e,抢购成功,当前抢购成功人数:1,真实剩余商品数量:9
用户succ7---04249eef-1304-4976-98c9-2a59fd21c6ca,抢购成功,当前抢购成功人数:3,真实剩余商品数量:7
用户fail---2d3e1846-c6fc-47d0-964d-82a96e5784c6,抢购失败,剩余商品数量:10,但此时无法获取真实剩余商品数量。

5.3 总结

(1)由5.1和5.2对比可知,当用户数量小于商品数量时,并发访问量越大,用户秒杀到商品的成功率就会越低,因为并发量越大,可以进行的秒杀轮数就会越少,能抢购到商品的用户也就越少。
(2)5.1和5.2中的假设其实是不合理的,如果用户数量小于商品数量,供大于求,那也就不应该存在高并发秒杀的概念了,即使此时强行制造秒杀这个概念,但因为库存充足,所以也应该让所有用户都抢购到商品,只是抢到的先后顺序不同而已。
一个真实的网上商城的秒杀活动应该存在如下关系:用户数量(在线)>> 商品数量 > 用户并发数,举例:
由1W台手机等待秒杀,在线等待秒杀活动开始的用户数量为10W,用户并发量为3k。


http://www.ppmy.cn/news/247181.html

相关文章

(学习日记)2023.06.06

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

mysql究竟是否适合运行在docker容器中

目前&#xff0c;容器和 Docker 依旧是技术领域最热门的词语&#xff0c;无状态的服务容器化已经是大势所趋&#xff0c;同时也带来了一个热点问题被大家所争论不以&#xff1a;数据库 MySQL 是否需要容器化&#xff1f; 文章目录 认真分析大家的各种观点&#xff0c;发现赞同者…

Redis主从集群与哨兵集群

一、Redis 哨兵集群原理 Redis 哨兵集群是一种高可用性的解决方案&#xff0c;用于监控 Redis 实例的状态并在实例出现故障时自动进行故障转移。 Redis 哨兵集群由多个哨兵实例组成&#xff0c;每个哨兵实例都运行在独立的服务器上。每个哨兵实例都会周期性地向 Redis 实例发…

【leetcode-mysql】1068. 产品销售分析 I

题目&#xff1a; 销售表 Sales&#xff1a; ------------------ | Column Name | Type | ------------------ | sale_id | int | | product_id | int | | year | int | | quantity | int | | price | int | ------------------ (sale_id, year) 是销售表 Sales 的主键. prod…

python3 爬虫相关学习7:初步摸索使用 BeautifulSoup

1 一个爬图片pic的代码的例子 下面这段是爬一些图片pic的代码学写了一段bs的代码&#xff0c;但是马上报错 #E:\work\FangCloudV2\personal_space\2learn\python3\py0001.txtimport requests from bs4 import BeautifulSoupurl"https://movie.douban.com/celebrity/10115…

java SSM 教务管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM 教务管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/…

[IJCAI 2022] 基于个性化掩码的实用安全联合推荐

Practical and Secure Federated Recommendation with Personalized Mask | SpringerLink 摘要 联合推荐解决了推荐系统的数据筒仓和隐私问题。目前的联合推荐系统主要利用密码学或混淆方法来保护原始评分不被泄露。然而&#xff0c;前者带来了额外的通信和计算成本&#xff0…