转自:https://blog.csdn.net/Roy_70/article/details/78260826

一、前言
在一些对高并发请求有限制的系统或者功能里,比如说秒杀活动,或者一些网站返回的当前用户过多,请稍后尝试。这些都是通过对同一时刻请求数量进行了限制,一般用作对后台系统的保护,防止系统因为过大的流量冲击而崩溃。对于系统崩溃带来的后果,显然还是拒绝一部分请求更能被维护者所接受。
而在各种限流中,除了系统自身设计的带锁机制的计数器外,利用Redis实现显然是一种既高效安全又便捷方便的方式。

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

127.0.0.1:6379> set num 10
OK
127.0.0.1:6379> incr num
(integer) 11
127.0.0.1:6379> get num # 数字值在 Redis 中以字符串的形式保存
"11"

  

注意: 由于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命令来实现两种方法解决这个问题。

四、流量控制之java实现
这里我们将在java中使用redis-incr的特性来构建一个1分钟内只允许 请求100次的控制代码,key代表在redis内存放的被控制的键值。

public static boolean flowControl(String key){
//最大允许100
int max = ;
long total = 1L;
try {
if (jedisInstance.get(key) == null) {
//jedisInstance是Jedis连接实例,可以使单链接也可以使用链接池获取,实现方式请参考之前的blog内容
//如果redis目前没有这个key,创建并赋予0,有效时间为60s
jedisInstance.setex(key, , "");
} else {
//获取加1后的值
total = jedisInstance.incr(redisKey).longValue();
//Redis TTL命令以秒为单位返回key的剩余过期时间。当key不存在时,返回-2。当key存在但没有设置剩余生存时间时,返回-1。否则,以秒为单位,返回key的剩余生存时间。
if (jedisInstance.ttl(redisKey).longValue() == -1L)
{
//为给定key设置生存时间,当key过期时(生存时间为0),它会被自动删除。
jedisInstance.expire(redisKey, );
}
}
} catch (Exception e) {
logger.error("流量控制组件:执行计数操作失败,无法执行计数");
}
long keytotaltransations = max;
//判断是否已超过最大值,超过则返回false
if (total > keytotaltransations) {
return false;
}
return true;
}

Redis原子计数器incr,防止并发请求的更多相关文章

  1. Redis原子计数器incr

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

  2. 如何使用redis计数器防止并发请求

    需求描述 最近项目中有个需求,短信发送的并发请求问题:业务需求是需要限制一个号码一分钟内只能获取一次随机码,之前的实现是短信发送请求过来后,先去数据库查询发送记录,根据上一次的短信发送时间和当前时间比 ...

  3. [Golang]-8 工作池、速率限制、原子计数器、互斥锁

    目录 工作池 速率限制 原子计数器 互斥锁 工作池 在这个例子中,我们将看到如何使用 Go 协程和通道实现一个工作池 . func worker(id int, jobs <-chan int, ...

  4. 如何配置IIS处理多并发请求及存在的问题

    很多时候多线程能快速高效独立的计算数据,应用比较多. 但今天遇到的多进程下的问题更是让人觉得复杂 多进程下static变量都要失效,就目前的平台和产品static使用是很多的,各种session.ca ...

  5. IIS处理并发请求时出现的问题及解决

    一个ASP.NET项目在部署到生产环境时,当用户并发量达到200左右时,IIS出现了明显的请求排队现象,发送的请求都进入等待,无法及时响 应,系统基本处于不可用状态.因经验不足,花了很多时间精力解决这 ...

  6. Web大规模高并发请求和抢购的解决方案

    电商的秒杀和抢购,对我们来说,都不是一个陌生的东西.然而,从技术的角度来说,这对于Web系统是一个巨大的考验.当一个Web系统,在一秒钟内收到数以万计甚至更多请求时,系统的优化和稳定至关重要.这次我们 ...

  7. IIS处理并发请求设置

    一个ASP.NET项目在部署到生产环境时,当用户并发量达到200左右时,IIS出现了明显的请求排队现象,发送的请求都进入等待,无法及时响应,系统基本处于不可用状态.   当发现请求明显延迟,没有被即时 ...

  8. 达达O2O后台架构演进实践:从0到4000高并发请求背后的努力

    1.引言   达达创立于2014年5月,业务覆盖全国37个城市,拥有130万注册众包配送员,日均配送百万单,是全国领先的最后三公里物流配送平台. 达达的业务模式与滴滴以及Uber很相似,以众包的方式利 ...

  9. CountDownLatch和CyclicBarrier模拟同时并发请求

    有时候要测试一下某个功能的并发能力,又不要想借助于其他测试工具,索性就自己写简单的demo模拟一个并发请求就最方便了.如果熟悉jemter的测试某接口的并发能力其实更专业,此处只是自己折腾着玩. Co ...

随机推荐

  1. 使用IDEA配置SpringBoot热部署无效解决

    首先检查自己pom.xml文件里是否有加入依赖 <dependency> <groupId>org.springframework.boot</groupId> & ...

  2. 【Nginx】Linux 环境下 Nginx 配置SSL 证书

    一.解压三个包到相同目录编译nginx cd /usr/local/src/nginx-1.12.2 # 将下列的包版本号换成自己下载的版本号 ./configure --prefix=/usr/lo ...

  3. JS将后台获取毫秒数转换为自定义格式日期

    重写prototype  Date.prototype.Format = function(fmt) { var o = { "M+" : this.getMonth()+1, / ...

  4. 一、基础篇--1.3进程和线程-CountDownLatch、CyclicBarrier 和 Semaphore

    下面对上面说的三个辅助类进行一个总结: 1)CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同: CountDownLatch一般用于某个线程A等待 ...

  5. oc 计算 带括号 式子

    下面代码实现可以计算 类似以下的字符窜. @"(1+2*(3+4)+3)/2" 自写一个简单 stack .不知道 OC为什么不提供Stack类. #import <Foun ...

  6. js evenloop

    一.宏任务 vs 微任务 1.macrotask setTimeOut . setInterval . setImmediate . I/O . 各种callback.UI渲染等 优先级: 主代码块 ...

  7. swift--【do..catch与try,try?,try!】

    throws抛出异常, 那么就必须通过try来处理 try : 标准的处理方式, 该方式必须结合do catch来处理 try? :告诉系统可能有错, 也可能没错, 如果发生错误, 那么返回nil, ...

  8. TortoiseSvn客户端介绍

    TortoiseSVN 是svn版本控制系统的一个免费开源客户端,它是svn版本控制的 Windows 扩展.可以使你避免使用枯燥而且不方便的命令行.它完全嵌入 Windows Explorer,使用 ...

  9. Popover 弹出框

    基础用法 Popover 的属性与 Tooltip 很类似,它们都是基于Vue-popper开发的,因此对于重复属性,请参考 Tooltip 的文档,在此文档中不做详尽解释. 设置索引ref,在按钮中 ...

  10. Docker在CentOS下的安装

    工欲善其事,必先利其器. 在我们以后的Docker学习中,都推荐使用CentOS6.5作为学习平台,毕竟Docker的内核也是基于Linux的.本文主要分享笔者在CentOS下的安装Docker的过程 ...