redis提供了rate limit demo 如下所示:

INCR key

Available since 1.0.0.

Time complexity: O(1)

Increments the number stored at key by one. If the key does not exist, it is set to 0 before performing the operation. An error is returned if the key contains a value of the wrong type or contains a string that can not be represented as integer. This operation is limited to 64 bit signed integers.

Note: this is a string operation because Redis does not have a dedicated integer type. The string stored at the key is interpreted as a base-10 64 bit signed integer to execute the operation.

Redis stores integers in their integer representation, so for string values that actually hold an integer, there is no overhead for storing the string representation of the integer.

Return value

Integer reply: the value of key after the increment

Examples

redis> SET mykey "10"

OK

redis> INCR mykey

(integer) 11

redis> GET mykey

"11"

redis>

Pattern: Counter

The counter pattern is the most obvious thing you can do with Redis atomic increment operations. The idea is simply send an INCR command to Redis every time an operation occurs. For instance in a web application we may want to know how many page views this user did every day of the year.

To do so the web application may simply increment a key every time the user performs a page view, creating the key name concatenating the User ID and a string representing the current date.

This simple pattern can be extended in many ways:

  • It is possible to use INCR and EXPIRE together at every page view to have a counter counting only the latest N page views separated by less than the specified amount of seconds.
  • A client may use GETSET in order to atomically get the current counter value and reset it to zero.
  • Using other atomic increment/decrement commands like DECR or INCRBY it is possible to handle values that may get bigger or smaller depending on the operations performed by the user. Imagine for instance the score of different users in an online game.

Pattern: Rate limiter

The rate limiter pattern is a special counter that is used to limit the rate at which an operation can be performed. The classical materialization of this pattern involves limiting the number of requests that can be performed against a public API.

We provide two implementations of this pattern using INCR, where we assume that the problem to solve is limiting the number of API calls to a maximum of ten requests per second per IP address.

Pattern: Rate limiter 1

The more simple and direct implementation of this pattern is the following:

FUNCTION LIMIT_API_CALL(ip)
ts = CURRENT_UNIX_TIME()
keyname = ip+":"+ts
current = GET(keyname)
IF current != NULL AND current > 10 THENERROR "too many requests per second"
ELSEMULTIINCR(keyname,1)EXPIRE(keyname,10)EXECPERFORM_API_CALL()
END

Basically we have a counter for every IP, for every different second. But this counters are always incremented setting an expire of 10 seconds so that they'll be removed by Redis automatically when the current second is a different one.

Note the used of MULTI and EXEC in order to make sure that we'll both increment and set the expire at every API call.

Pattern: Rate limiter 2

An alternative implementation uses a single counter, but is a bit more complex to get it right without race conditions. We'll examine different variants.

FUNCTION LIMIT_API_CALL(ip):
current = GET(ip)
IF current != NULL AND current > 10 THENERROR "too many requests per second"
ELSEvalue = INCR(ip)IF value == 1 THENEXPIRE(value,1)ENDPERFORM_API_CALL()
END

The counter is created in a way that it only will survive one second, starting from the first request performed in the current second. If there are more than 10 requests in the same second the counter will reach a value greater than 10, otherwise it will expire and start again from 0.

In the above code there is a race condition. If for some reason the client performs the INCR command but does not perform the EXPIRE the key will be leaked until we'll see the same IP address again.

This can be fixed easily turning the INCR with optional EXPIRE into a Lua script that is send using the EVAL command (only available since Redis version 2.6).

local current
current = redis.call("incr",KEYS[1])
if tonumber(current) == 1 thenredis.call("expire",KEYS[1],1)
end

There is a different way to fix this issue without using scripting, but using Redis lists instead of counters. The implementation is more complex and uses more advanced features but has the advantage of remembering the IP addresses of the clients currently performing an API call, that may be useful or not depending on the application.

FUNCTION LIMIT_API_CALL(ip)
current = LLEN(ip)
IF current > 10 THENERROR "too many requests per second"
ELSEIF EXISTS(ip) == FALSEMULTIRPUSH(ip,ip)EXPIRE(ip,1)EXECELSERPUSHX(ip,ip)ENDPERFORM_API_CALL()
END

The RPUSHX command only pushes the element if the key already exists.

Note that we have a race here, but it is not a problem: EXISTS may return false but the key may be created by another client before we create it inside the MULTI / EXEC block. However this race will just miss an API call under rare conditions, so the rate limiting will still work correctly.

转载于:https://www.cnblogs.com/davidwang456/p/3972244.html

redis 控制调用频率相关推荐

  1. Redis控制调用频率

    网站功能中好多地方用到了调用或访问频率的统计.限制,利用Redis可以实现访问频次的限制. Redis官网中对incr命令的介绍中讲到了关于如何用redis来做rate limit的探讨. 官网地址为 ...

  2. 控制ASP.NET Web API 调用频率与限流

    ASP.NET MVC 实现 https://github.com/stefanprodan/MvcThrottle ASP.NET WEBAPI 实现 https://github.com/stef ...

  3. Redis Java调用

    Redis Java调用 package com.stono.redis;import redis.clients.jedis.Jedis;public class RedisJava {public ...

  4. java对外接口安全问题_怎么保证对外暴露接口的安全性(调用频率限制)

    如何限制接口调用者对接口的调用频率? 问题:对某个对外暴露的接口加一个限制:调用者一分钟之内调用次数不能超过100次,如果超过100次就直接返回给调用者失败的信息. 给调用者一个SECRET,每次调用 ...

  5. 微信开发之——接口调用频率xianzh

    公众号调用接口并不是无限制的.为了防止公众号的程序错误而引发微信服务器负载异常,默认情况下,每个公众号调用接口都不能超过一定限制时,调用对应接口会收到如下错误返回码: {"errcode&q ...

  6. 信捷PLC与7台三菱变频器485通讯案例 对7台变频器进行单独频率设定,启停控制,频率读取

    信捷PLC与7台三菱变频器485通讯案例功能:用信捷PLC与7台三菱变频器modbus通讯,自由通讯协议 配件:信捷XC系列PLC,三菱E740变频器,昆仑通态触摸屏 功能:对7台变频器进行单独频率设 ...

  7. redis远程调用实习笔记

    Redis远程调用学习笔记 找到redis的安 装目录 修改配置文件redis.conf配置文件:(注释掉bind:127.0.0.1)和修改保护模式为no 修改另一个配置文件:

  8. .Net 如何模拟会话级别的信号量,对http接口调用频率进行限制(有demo)

    现在,因为种种因素,你必须对一个请求或者方法进行频率上的访问限制.  比如, 你对外提供了一个API接口,注册用户每秒钟最多可以调用100次,非注册用户每秒钟最多可以调用10次. 比如, 有一个非常吃 ...

  9. php redis 短信频率,发送短信: 使用Redis限制每天的发送频率和发送时间

    ratelimiting.lua --[[实现访问频率的脚本.参数:KEY[1] 用来标识同一个用户的idARGV[1] 过期时间ARGV[2] 过期时间内可以访问的次数返回值: 如果没有超过指定的频 ...

最新文章

  1. CodeGen标记循环
  2. php png jpg,php如何将png转换成jpg-PHP问题
  3. INotifyPropertyChanged 接口 CallerMemberName属性
  4. 关于ASP.NET 中站点地图sitemap 的使用
  5. mysql中如何把字符串转换成日期类型
  6. 线上squid防火墙配置
  7. Java EE拦截器
  8. android长按home键关闭程序,应用程序退出后Dialog弹出
  9. python getattr函数_Python中的getattr()函数详解
  10. 视觉SLAM笔记(63) RGB-D 稠密建图
  11. 关于MATLAB实现的数字信号处理(二)
  12. Linux下tomcat 8安装与配置
  13. 小波分析工具包 matlab,matlab小波工具箱下载|
  14. 观察者模式(行为型)
  15. Dynamic Web Module 4.0 requires Java 1.8 or newer.
  16. python爬取喜马拉雅音频
  17. 战略盲区,是看不见,还是不想看见?
  18. Adobe Photoshop CS5永久序列号
  19. python另存为excel_为什么不能从python代码中“另存为”Excel文件?
  20. 到底什么是范数?什么是0范数、1范数、2范数?区别又是什么?

热门文章

  1. python中find函数忽略大小写_python字符串(大小写、判断、查找、分割、拼接、裁剪、替换、格式化)...
  2. python绘制一个圆_Python在网格上绘制一个填充的“圆”
  3. python回归分析预测模型_Python与线性回归模型预测房价
  4. matlab求一个方程组的系数矩阵,【求解】matlab求解非齐次方程组,但是系数矩阵是复数,求帮忙...
  5. python窗体应用程序无阻塞_Python,matplotlib pyplot show()未阻塞
  6. 变频器输出功率_变频器的输出功率该如何选择?
  7. 对计算机技术的发展方向研究,网络技术发展对计算机技术的影响
  8. mysql 连接查询两个条件_MySQL之多表查询一 介绍 二 多表连接查询 三 符合条件连接查询 四 子查询 五 综合练习...
  9. 双linux grub rescue,Grub Rescue修复方法
  10. Linux下CMake简明教程(四)不同目录下多个源文件