redis計(jì)數(shù)器與數(shù)量控制的實(shí)現(xiàn)
命令行命令:
127.0.0.1:6379> exists mycounter (integer) 0 127.0.0.1:6379> set mycounter 99 //設(shè)置一個(gè)值 OK 127.0.0.1:6379> get mycounter //獲得一個(gè)值 "99" 127.0.0.1:6379> incr mycounter //對(duì)計(jì)數(shù)器進(jìn)行增加操作 (integer) 100 127.0.0.1:6379> get mycounter "100" 127.0.0.1:6379> incrby mycounter 2 //對(duì)計(jì)數(shù)器進(jìn)行+2操作 (integer) 102 127.0.0.1:6379> get mycounter "102" 127.0.0.1:6379> incrby mycounter -2 //對(duì)計(jì)數(shù)器進(jìn)行-2操作 (integer) 100 127.0.0.1:6379> get mycounter "100" 127.0.0.1:6379> setnx mycounter 99 //當(dāng)Key不存在時(shí),設(shè)置這個(gè)值 (integer) 0 127.0.0.1:6379> setnx mycounter1 99 //當(dāng)Key不存在時(shí),設(shè)置這個(gè)值 (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的生存時(shí)間 (integer) 1 127.0.0.1:6379> ttl mycounter //獲得key的生存時(shí)間 (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)用場(chǎng)景:
- 商品搶購(gòu)
- 抽獎(jiǎng)限量
- 搶紅包
改進(jìn):
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("記個(gè)日志:{}", 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("記個(gè)日志:{}", 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ā)送請(qǐng)求:
向v2發(fā)送請(qǐng)求:
到此這篇關(guān)于redis計(jì)數(shù)器與數(shù)量控制的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)redis計(jì)數(shù)器與數(shù)量控制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
redis中token失效引發(fā)的一次生產(chǎn)事故
項(xiàng)目再測(cè)試的時(shí)候發(fā)現(xiàn)不定時(shí)token失效,本文主要介紹了redis中token失效引發(fā)的一次生產(chǎn)事故,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-03-03通過(guò)docker和docker-compose安裝redis兩種方式詳解
這篇文章主要介紹了通過(guò)docker和docker-compose安裝redis的兩種方式,Docker安裝方式包括拉取鏡像、查看本地鏡像、運(yùn)行容器和測(cè)試連接,Docker Compose安裝方式包括目錄結(jié)構(gòu)、配置文件、啟動(dòng)和關(guān)閉容器、檢查啟動(dòng)情況以及查看CPU和內(nèi)存使用狀態(tài),需要的朋友可以參考下2024-12-12Redis集群模式和常用數(shù)據(jù)結(jié)構(gòu)詳解
Redis集群模式下的運(yùn)維指令主要用于集群的搭建、管理、監(jiān)控和維護(hù),講解了一些常用的Redis集群運(yùn)維指令,本文重點(diǎn)介紹了Redis集群模式和常用數(shù)據(jù)結(jié)構(gòu),需要的朋友可以參考下2024-03-03Redis整合Spring結(jié)合使用緩存實(shí)例
這篇文章主要介紹了Redis整合Spring結(jié)合使用緩存實(shí)例,介紹了如何在Spring中配置redis,并通過(guò)Spring中AOP的思想,將緩存的方法切入到有需要進(jìn)入緩存的類或方法前面。需要的朋友可以參考下2015-12-12Redis如何使用HyperLogLog的實(shí)現(xiàn)
本文主要介紹了Redis如何使用HyperLogLog的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06