解决方案:重复抢单 Redis原子计数器incr


关键词

  • Redis Incr 操作 key(用户信息) 判断value>1

比如秒杀活动:通过对同一时刻请求数量进行了限制,一般用作对后台系统的保护,防止系统因为过大的流量冲击而崩溃。对于系统崩溃带来的后果,显然还是拒绝一部分请求更能被维护者所接受

而在各种限流中,除了系统自身设计的带锁机制的计数器外,利用Redis实现显然是一种既高效安全又便捷方便的方式

一、incr命令

Redis Incr 命令将 key 中储存的数字值增一
如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作
如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误
本操作的值限制在 64 位(bit)有符号数字表示之内

注意:

由于redis并没有一个明确的类型来表示整型数据,所以这个操作是一个字符串操作
执行这个操作的时候,key对应存储的字符串被解析为10进制的64位有符号整型数据
事实上,Redis 内部采用整数形式(Integer representation)来存储对应的整数值,所以对该类字符串值实际上是用整数保存,也就不存在存储整数的字符串表示(String representation)所带来的额外消耗

使用场景

1.计数器
使用思路是:每次有相关操作的时候,就向Redis服务器发送一个incr命令

例如这样一个场景:我们有一个web应用,我们想记录每个用户每天访问这个网站的次数
web应用只需要通过拼接用户id和代表当前时间的字符串作为key,每次用户访问这个页面的时候对这个key执行一下incr命令

这个场景可以有很多种扩展方法:
通过结合使用INCR和EXPIRE命令,可以实现一个只记录用户在指定间隔时间内的访问次数的计数器

客户端可以通过GETSET命令获取当前计数器的值并且重置为0
通过类似于DECR或者INCRBY等原子递增/递减的命令,可以根据用户的操作来增加或者减少某些值 比如在线游戏,需要对用户的游戏分数进行实时控制,分数可能增加也可能减少

2.限速器
限速器是一种可以限制某些操作执行速率的特殊场景
传统的例子就是限制某个公共api的请求数目

假设我们要解决如下问题:限制某个api每秒每个ip的请求次数不超过10次
我们可以通过incr命令来实现两种方法解决这个问题

二、实践

    /*** 下单** @param time* @param id* @param username*/@Overridepublic void add(String time, Long id, String username) {/*** 解决重复抢单问题:(即使多线程同时请求,redis是单线程的,也没问题)** */Long userQueueCount = redisTemplate.boundHashOps("UserQueueCount").increment(username, 1);if (userQueueCount > 1) {throw new RuntimeException("重复抢单!!!");}//... ...后续下单操作}

解决方案:重复抢单(Redis原子计数器incr)相关推荐

  1. 利用Redis原子计数器incr实现计数器及接口限流

    一.INCR命令介绍 Redis Incr 命令将 key 中储存的数字值增一. 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作.且将key的有效时间设置为长 ...

  2. Redis原子计数器incr,防止并发请求

    一.前言 在一些对高并发请求有限制的系统或者功能里,比如说秒杀活动,或者一些网站返回的当前用户过多,请稍后尝试.这些都是通过对同一时刻请求数量进行了限制,一般用作对后台系统的保护,防止系统因为过大的流 ...

  3. java redis计数器_使用Redis原子计数器incr实现限速器功能

    点击上方☝ Java编程技术乐园,轻松关注~ 及时获取有趣有料的 技术文章 做一个积极的人编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 一.前言 在一些对高并发请求有限制的系统或者功能 ...

  4. redis mysql 原子计数器_Redis原子计数器incr

    一.前言 在一些对高并发请求有限制的系统或者功能里,比如说秒杀活动,或者一些网站返回的当前用户过多,请稍后尝试.这些都是通过对同一时刻请求数量进行了限制,一般用作对后台系统的保护,防止系统因为过大的流 ...

  5. java redis计数器_Redis原子计数器incr,防止并发请求

    一.前言 在一些对高并发请求有限制的系统或者功能里,比如说秒杀活动,或者一些网站返回的当前用户过多,请稍后尝试.这些都是通过对同一时刻请求数量进行了限制,一般用作对后台系统的保护,防止系统因为过大的流 ...

  6. redis mysql 原子计数器_使用redis的increment()方法实现计数器功能案例

    一直知道redis可以用来实现计数器功能,但是之前没有实际使用过,昨天碰到一个需求:用户扫码当天达到20次即提示:当日扫码次数达到上限! 当时就想到使用redis的递增方法increment()来实现 ...

  7. Redis实现计数器---接口防刷---升级版(Redis+Lua)

    [前言] Cash Loan(一):Redis实现计数器---接口防刷  中介绍了项目中应用redis来做计数器的实现过程,最近自己看了些关于Redis实现分布式锁的代码后,发现在Redis分布式锁中 ...

  8. 秒杀场景_重复抢单问题分析与实现_03

    文章目录 SkillGoodService 改造 SkillGoodService 改造 package com.gblfy.service;import com.gblfy.dao.SkillOrd ...

  9. 记一次秒杀重复抢单问题

    背景描述: 系统给APP用户(客户经理)定时推送一批客户资源数据,这批数据在不同的客户经理登录APP都能看见,然后点击抢的按钮,就可以获取这个客户了,这种场景类似于秒杀抢单,存在多人同时点击按钮抢人, ...

最新文章

  1. android除去标题栏或全屏
  2. java动态定义泛型_关于oop:具有动态性质且可完全自定义的Java泛型编程
  3. Spring MVC前端控制器不拦截静态资源配置
  4. 数据结构系列之大话数据结构
  5. diabetes影响因子2017_瑞金医院创办Journal of Diabetes成为亚太地区影响因子最高的糖尿病学术期刊...
  6. P80 例4-1 名和姓的对换问题。英国人和美国人姓名的书写形式是“名在前,姓在后”,但在有些情况下,需要把姓名写成“姓在前,名在后,中间加一个逗号”的形式。编写一个程序实现把“名在前,姓在后”的姓名
  7. OAuth2授权方式
  8. DataGrip 安装教程 详细版
  9. 【教程】在word中如何替换文字,新手请绕道!
  10. [前端积累]--响应式布局(三)
  11. Python工具函数
  12. [Bug] Spring相关bug收集
  13. 完爆90%的性能毛病,收好数据库优化八大通用绝招
  14. layui动态添加的表单元素显示异常
  15. 警惕!最新勒索病毒incaseformat来袭!清除方法如下!
  16. jq 实现无缝轮播图
  17. 学电脑编程入门要先学习什么
  18. php carbon 格式化,PHP Carbon
  19. 【Java进阶篇】第一章 面向对象(上篇)
  20. 深度学习_GAN_GAN优化训练方法汇总(全网最全,持续更新)

热门文章

  1. 前端开发人员所必备的十大技能
  2. 触发器-当表1插入数据时将表1的数据插入表2
  3. (纪录片)电的故事 Shock Awe The Story of Electricity
  4. 黑马程序员-Java-面向对象篇上《二》
  5. ***常用的***手段
  6. java学习笔记 --- 多线程(多线程的控制)
  7. 5.7 Components — Sending Actions From Components to Your Application
  8. mariadb备份与恢复工具
  9. STM32学习笔记(7):USART串口的使用
  10. SilverLight4调用WebService跨域访问问题