redis计数器与数量控制

命令行命令:

java 复制代码
127.0.0.1:6379> exists mycounter
(integer) 0
127.0.0.1:6379> set mycounter 99 //设置一个值
OK
127.0.0.1:6379> get mycounter  //获得一个值
"99"
127.0.0.1:6379> incr mycounter //对计数器进行增加操作
(integer) 100
127.0.0.1:6379> get mycounter
"100"
127.0.0.1:6379> incrby mycounter 2 //对计数器进行+2操作
(integer) 102
127.0.0.1:6379> get mycounter
"102"
127.0.0.1:6379> incrby mycounter -2 //对计数器进行-2操作
(integer) 100
127.0.0.1:6379> get mycounter
"100"
127.0.0.1:6379> setnx mycounter 99 //当Key不存在时,设置这个值
(integer) 0
127.0.0.1:6379> setnx mycounter1 99  //当Key不存在时,设置这个值
(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 //设置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

数量控制器应用场景:

  • 商品抢购
  • 抽奖限量
  • 抢红包

++改进:++


java 复制代码
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.保存数据
        strOperations.set("name", "imooc2");
        // 3. 获取数据
        String value = strOperations.get("name");


        log.info("记个日志:{}", value);
        return ResponseUtils.res(value);
    }

    @GetMapping("/v3")
    @ApiOperation(value = "方法v3")
    public ResponseEntity<Data<String>> demoV3() {


        // 2.保存数据
        stringRedisTemplate.opsForValue().set("name", "imooc3");
        // 3. 获取数据
        String value = stringRedisTemplate.opsForValue().get("name");


        log.info("记个日志:{}", value);
        return ResponseUtils.res(value);
    }

    /**
     * 数量控制器v1
     *
     * @return
     */
    @GetMapping("/count/v1")
    @ApiOperation(value = "数量控制器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());
    }

    /**
     * 数量控制器v2
     *
     * @return
     */
    @GetMapping("/count/v2")
    @ApiOperation(value = "数量控制器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发送请求:

向v2发送请求:


视频学习地址

相关推荐
Momo__28 分钟前
VueUse createReusableTemplate —— 单文件组件内的模板复用神器
前端·vue.js
程序员小富34 分钟前
我开源了一个开发者专属的智能 JSON 工具,得到了媳妇高度认可
前端·vue.js·后端
小小小小宇34 分钟前
程序员如何给 LLM 装工具以及看懂推理过程
前端
写代码的皮筏艇34 分钟前
React中的forwardRef
前端·react.js·面试
槑有老呆43 分钟前
花三个月工资请了个 AI 程序员,结果它连青岛啤酒股价都查不了
前端
风骏时光牛马1 小时前
Verilog开发常见问题汇总解析
前端
子兮曰1 小时前
AI Coding Method Map:一张图看懂 AI 编程的完整链路
前端·人工智能·后端
weedsfly1 小时前
语法糖褪去之后——Babel 转译产物中的 JavaScript 本貌
前端·javascript
JustHappy1 小时前
「软件设计思想杂谈🤔」“切图仔”也能懂编译原理?框架源码也许没那么难。聊聊 Vue 的编译(上)
前端·javascript·vue.js