redis計數(shù)器與數(shù)量控制的實現(xiàn)
更新時間:2023年12月19日 10:12:13 作者:愚人釗呀
使用Redis計數(shù)器可以輕松地解決數(shù)量控制的問題,同時還能有效地提高應(yīng)用的性能,本文主要介紹了redis計數(shù)器與數(shù)量控制的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
命令行命令:
127.0.0.1:6379> exists mycounter (integer) 0 127.0.0.1:6379> set mycounter 99 //設(shè)置一個值 OK 127.0.0.1:6379> get mycounter //獲得一個值 "99" 127.0.0.1:6379> incr mycounter //對計數(shù)器進行增加操作 (integer) 100 127.0.0.1:6379> get mycounter "100" 127.0.0.1:6379> incrby mycounter 2 //對計數(shù)器進行+2操作 (integer) 102 127.0.0.1:6379> get mycounter "102" 127.0.0.1:6379> incrby mycounter -2 //對計數(shù)器進行-2操作 (integer) 100 127.0.0.1:6379> get mycounter "100" 127.0.0.1:6379> setnx mycounter 99 //當Key不存在時,設(shè)置這個值 (integer) 0 127.0.0.1:6379> setnx mycounter1 99 //當Key不存在時,設(shè)置這個值 (integer) 1 127.0.0.1:6379> get mycounter1 "99" 127.0.0.1:6379> get mycounter "100" 127.0.0.1:6379> expire mycounter 30 //設(shè)置key的生存時間 (integer) 1 127.0.0.1:6379> ttl mycounter //獲得key的生存時間 (integer) 19 127.0.0.1:6379> ttl mycounter (integer) -1 127.0.0.1:6379> exists mycounter (integer) 1 127.0.0.1:6379> ttl mycounter (integer) -1
數(shù)量控制器應(yīng)用場景:
- 商品搶購
- 抽獎限量
- 搶紅包
改進:
package com.example.demo.controller; import com.example.demo.util.ResponseUtils; import com.example.demo.util.dto.Data; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.Objects; import java.util.concurrent.TimeUnit; @RestController @RequestMapping(value = "/demo") @Slf4j public class DemoController { @Autowired private ValueOperations<String, String> strOperations; @Autowired private StringRedisTemplate stringRedisTemplate; @Autowired private ValueOperations<String, Integer> intOperations; @Autowired private RedisTemplate<String, Integer> intRedisTemplate; public static final String PREFIX = "mycounter_"; @GetMapping("/v2") @ApiOperation(value = "方法v2") public ResponseEntity<Data<String>> demoV2() { // 2.保存數(shù)據(jù) strOperations.set("name", "imooc2"); // 3. 獲取數(shù)據(jù) String value = strOperations.get("name"); log.info("記個日志:{}", value); return ResponseUtils.res(value); } @GetMapping("/v3") @ApiOperation(value = "方法v3") public ResponseEntity<Data<String>> demoV3() { // 2.保存數(shù)據(jù) stringRedisTemplate.opsForValue().set("name", "imooc3"); // 3. 獲取數(shù)據(jù) String value = stringRedisTemplate.opsForValue().get("name"); log.info("記個日志:{}", value); return ResponseUtils.res(value); } /** * 數(shù)量控制器v1 * * @return */ @GetMapping("/count/v1") @ApiOperation(value = "數(shù)量控制器v1") public ResponseEntity<Data<String>> countV1() { String key = PREFIX + "v1"; int amountLimit = 100; int incrAmount = 1; if (Objects.isNull(intOperations.get(key))) { intOperations.set(key, 95); } Integer currAmount = intOperations.get(key); if (currAmount + incrAmount > amountLimit) { log.info(" Bad Luck :{},{},currAmount + incrAmount > amountLimit={}", key, amountLimit,currAmount + incrAmount > amountLimit); } else { intOperations.set(key, currAmount + incrAmount); log.info(" Good Luck :{},{},currAmount + incrAmount > amountLimit={}", key, amountLimit,currAmount + incrAmount > amountLimit); } return ResponseUtils.res(currAmount.toString()); } /** * 數(shù)量控制器v2 * * @return */ @GetMapping("/count/v2") @ApiOperation(value = "數(shù)量控制器v2") public ResponseEntity<Data<String>> countV2() { String key = PREFIX + "v2"; int amountLimit = 100; Long incrAmount = 1L; int startValue = 95; if (!intRedisTemplate.hasKey(key)) { intRedisTemplate.opsForValue().setIfAbsent(key, startValue); } Integer currAmount = intRedisTemplate.opsForValue().get(key); Long increment = intRedisTemplate.opsForValue().increment(key, incrAmount); if (increment.intValue() > amountLimit) { log.info(" Bad Luck :{},{}", key, amountLimit); } else { log.info(" Good Luck :{},{}", key, amountLimit); } return ResponseUtils.res(currAmount.toString()); } }
利用apipost向v1發(fā)送請求:
向v2發(fā)送請求:
到此這篇關(guān)于redis計數(shù)器與數(shù)量控制的實現(xiàn)的文章就介紹到這了,更多相關(guān)redis計數(shù)器與數(shù)量控制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
redis中token失效引發(fā)的一次生產(chǎn)事故
項目再測試的時候發(fā)現(xiàn)不定時token失效,本文主要介紹了redis中token失效引發(fā)的一次生產(chǎn)事故,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧2024-03-03通過docker和docker-compose安裝redis兩種方式詳解
這篇文章主要介紹了通過docker和docker-compose安裝redis的兩種方式,Docker安裝方式包括拉取鏡像、查看本地鏡像、運行容器和測試連接,Docker Compose安裝方式包括目錄結(jié)構(gòu)、配置文件、啟動和關(guān)閉容器、檢查啟動情況以及查看CPU和內(nèi)存使用狀態(tài),需要的朋友可以參考下2024-12-12Redis集群模式和常用數(shù)據(jù)結(jié)構(gòu)詳解
Redis集群模式下的運維指令主要用于集群的搭建、管理、監(jiān)控和維護,講解了一些常用的Redis集群運維指令,本文重點介紹了Redis集群模式和常用數(shù)據(jù)結(jié)構(gòu),需要的朋友可以參考下2024-03-03