老熟女激烈的高潮_日韩一级黄色录像_亚洲1区2区3区视频_精品少妇一区二区三区在线播放_国产欧美日产久久_午夜福利精品导航凹凸

重慶分公司,新征程啟航

為企業提供網站建設、域名注冊、服務器等服務

Redis實現秒殺的問題怎么解決

本篇內容介紹了“redis實現秒殺的問題怎么解決”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

我們提供的服務有:做網站、成都網站建設、微信公眾號開發、網站優化、網站認證、水城ssl等。為超過千家企事業單位解決了網站和推廣的問題。提供周到的售前咨詢和貼心的售后服務,是有科學管理、有技術的水城網站制作公司

Redis實現秒殺的問題怎么解決

1、秒殺邏輯

秒殺:解決計數器和人員記錄的事務操作

  1. 1.uid和proid非空判斷

  2. 2.連接redis

  3. 3.拼接key

    • 庫存key

    • 秒殺成功用戶key

  4. 4.獲取庫存,如果庫存為null,秒殺還沒開始

  5. 5.判斷用戶是否重復秒殺操作

  6. 6.判斷商品數量,庫存數量小于1,秒殺結束

  7. 7.秒殺過程

    • 庫存-1

    • 把秒殺成功用戶添加清單里面

2、存在問題

2.1、連接超時

原因:由于大量創建連接,十分消耗性能,并且有時獲取連接不及時,出現連接超時的情況

2.2、超賣

在并發的情況下發生的,就是在輸出沒有庫存(秒殺結束)后還有商品售出導致庫存數量為負數。
Redis實現秒殺的問題怎么解決

2.3、庫存遺留

使用樂觀鎖解決問題2之后,出現問題3

如果庫存數量相對并發更多,由于使用樂觀鎖,第一個用戶秒殺成功后會修改庫存鍵的版本號,其他搶到的用戶會因為版本號不同導致無法繼續購買,就會有庫存遺留問題

3、解決

3.1、連接超時

使用連接池,工具類如下:

public class JedisPoolUtil {
	private static volatile JedisPool jedisPool = null;
	private JedisPoolUtil() {
	}
	public static JedisPool getJedisPoolInstance() {
		if (null == jedisPool) {
			synchronized (JedisPoolUtil.class) {
				if (null == jedisPool) {
					JedisPoolConfig poolConfig = new JedisPoolConfig();
					poolConfig.setMaxTotal(200);
					poolConfig.setMaxIdle(32);
					poolConfig.setMaxWaitMillis(100 * 1000);
					poolConfig.setBlockWhenExhausted(true);
					poolConfig.setTestOnBorrow(true);
					jedisPool = new JedisPool(poolConfig, "127.0.0.1", 6379, 60000);
				}
			}
		}
		return jedisPool;
	}}//使用JedisPool jedisPoolInstance = JedisPoolUtil.getJedisPoolInstance();Jedis jedis = jedisPoolInstance.getResource();

springBoot版本(pom.xml引入,application.yml配置,然后注入對象即可)


    org.springframework.boot
    spring-boot-starter-data-redis
    redis.clients
    jedis
    3.2.0
spring:
  redis:
    host: 127.0.0.1    port: 6379
    database: 0
    timeout: 1800000
    lettuce:
      pool:
        max-active: 20
        max-wait: -1
        max-idle: 5
        min-idle: 0
    @Autowired
    private RedisTemplate redisTemplate;

3.2、超賣問題

使用Redis事務,樂觀鎖 + watch

//監視庫存
jedis.watch(kcKey);//中間代碼忽略

//7 秒殺過程
//使用事務
Transaction multi = jedis.multi();//組隊操作
multi.decr(kcKey);multi.sadd(userKey,uid);//執行
List results = multi.exec();if(results == null || results.size()==0) {
    System.out.println("秒殺失敗了....");
    jedis.close();
    return false;}

3.3、樂觀鎖導致的庫存遺留問題

使用Lua嵌入式腳本語言

  1. 將復雜的或者多步的 Redis 操作,寫為一個腳本,一次提交給Redis運行,減少反復連接 reids的次數。提升性能。

  2. LUA腳本是類似 redis 事務,有一定的原子性,不會被其他命令插隊,可以完成redis事務性的操作

  3. LUA腳本功能,在Redis 2.6以上的版本才可以使用

  4. 利用 lua 腳本淘汰用戶,解決超賣問題。

  5. redis 2.6 版本以后,通過 lua 腳本解決爭搶問題,實際上是 redis 利用其單線程的特性,用任務隊列的方式解決多任務并發問題

local userid=KEYS[1];				//1、2行定義兩個變量,					
local prodid=KEYS[2];
local qtkey="sk:"..prodid..":qt";	//3,4行定義拼接key
local usersKey="sk:"..prodid..":usr";
local userExists=redis.call("sismember",usersKey,userid); //5-8,判斷用戶是否存在,不存在return 2
if tonumber(userExists)==1 then
    return2;
end
local num=redis.call("get",qtkey);	//9-11,判斷商品是否存在
if tonumber(num)<=0 then
    return 0;
else								//12-15,用戶和商品操作
    redis.call("decr",qtkey);
    redis.call("sadd",usersKey,userid);
end
return1;  							//最后一行return 1;  秒殺成功

完整代碼如下:

// 定義兩段Lua腳本(使用Lua腳本可以解決樂觀鎖帶來的庫存遺留問題)
	static String secKillScript =
			"local userid=KEYS[1];\r\n" +
					"local prodid=KEYS[2];\r\n" +
					"local qtkey='sk:'..prodid..\":qt\";\r\n" +
					"local usersKey='sk:'..prodid..\":usr\";\r\n" +
					"local userExists=redis.call(\"sismember\",usersKey,userid);\r\n" +
					"if tonumber(userExists)==1 then \r\n" +
					"   return 2;\r\n" +
					"end\r\n" +
					"local num= redis.call(\"get\" ,qtkey);\r\n" +
					"if tonumber(num)<=0 then \r\n" +
					"   return 0;\r\n" +
					"else \r\n" +
					"   redis.call(\"decr\",qtkey);\r\n" +
					"   redis.call(\"sadd\",usersKey,userid);\r\n" +
					"end\r\n" +
					"return 1" ;
 
 
	public static boolean doSecKill(String uid,String prodid) throws IOException {
 
		JedisPool jedispool =  JedisPoolUtil.getJedisPoolInstance();
		Jedis jedis=jedispool.getResource();
		jedis.select(2);
 
		// 通過jedis的scriptLoad方法加載Lua腳本
		String sha1=  jedis.scriptLoad(secKillScript);
		//通過jedis的evalsha方法調用Lua腳本
		Object result= jedis.evalsha(sha1, 2, uid,prodid);
 
		String reString=String.valueOf(result);
		if ("0".equals( reString )  ) {
			System.err.println("已搶空!!");
		}else if("1".equals( reString )  )  {
			System.out.println("搶購成功!!!!");
		}else if("2".equals( reString )  )  {
			System.err.println("該用戶已搶過!!");
		}else{
			System.err.println("搶購異常!!");
		}
		jedis.close();
		return true;
	}

“Redis實現秒殺的問題怎么解決”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注創新互聯網站,小編將為大家輸出更多高質量的實用文章!


網站題目:Redis實現秒殺的問題怎么解決
瀏覽路徑:http://www.xueling.net.cn/article/ijigdp.html 主站蜘蛛池模板: 日韩超碰人人爽人人做人人添 | 久久亚洲精品情侣 | 日本一区二区三区视频在线播放 | 中文字幕丰满人伦在线 | 精品久久久久久久一区二区蜜臀 | 欧美色蜜桃97 | 青青草娱乐视频 | 无码人妻毛片丰满熟妇区毛片国产 | 伊人七七 | 日韩在线免费网站 | www.亚洲综合 | 男女啪啪永久免费网站 | 思思99热精品免费观看 | 在线中文字幕有码中文 | 在线观看黄色免费 | 欧美人与拘牲交大全视频 | 伦伦影院午夜理论片 | 人妻无码中文专区久久五月婷 | 欧美日韩国产在线一区 | 国产又黄又猛又粗又爽的A片 | 少妇大叫太大太爽受不了在线观看 | 国产性一级片 | 五月天人体艺术 | 91麻豆精品国产91久久久更新资源速度超快 | 91精品国模一区二区三区 | 亚洲富人天堂视频 | 久久久国产乱子伦精品 | swag破解版 | 亚洲Av纯肉无码精品动漫 | 久久国产亚洲高清观看 | 在线观看欧美激情 | 日本视频中文字幕 | 七妺福利精品导航大全 | 国产日韩精品一区二区三区在线 | 91视频免费入口 | 国产免费看插插插视频 | 国产一级做a爰片在线看免费 | 大帝av在线一区二区三区 | 一本久道高清无码视频 | 91精品久久久久久久久久 | 欧美精品一区二区三区在线四季 |