两个简单的API限流实现方案
1, Ngnix限流
Nginx在架构中起到请求转发与负载均衡器的作用。外部req首先到Nginx监听的80端口,然后Nginx将req交给到监听8080端口的APP服务器处理。处理结果再经由Nginx返回给调用方。
Nginx限流的配置:(/usr/local/etc/nginx/nginx.conf)
#user nobody;
worker_processes 1; events {
worker_connections 1024;
} http {
include mime.types;
default_type application/octet-stream; sendfile on;
keepalive_timeout 65; # Rate limitation conf
limit_req_zone $binary_remote_addr zone=mylimit:1m rate=1r/s;
server {
listen 80;
server_name localhost; location / {
root html;
index index.html index.htm;
} error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
} # rate limitation and redirection to APP
location ~* /(inventories|prices) {
limit_req zone=mylimit;
proxy_pass http://localhost:8080;
}
}
include servers/*;
}
其中, limit_req_zone $binary_remote_addr zone=mylimit:1m rate=1r/s;
将流量限制为 1QPS,如调用方超过该限制则返回 503
重启nginx: sudo nginx -s reload
2, Redis 计数器
原理: 每个req都对redis中生命周期为一个时间单位的计数器(key:callLimit)加1,如果单位时间内的访问次数超过限制,则拒绝所有后来的请求直到下一个单位时间开始。
public Mono<ServerResponse> req_handle(ServerRequest request) {
if (callLimitCheck()){
return getResp(request){
… business logics to handle the req …
};
} else {
return ServerResponse.ok().body(Mono.just(“Over call limit!”), String.class);
}
}
private boolean callLimitCheck() {
String callLimit = this.template.opsForValue().get("callLimit");
if(callLimit != null && Integer.valueOf(callLimit)>30) {
return false;
}
DefaultRedisScript<String> script = new DefaultRedisScript<>(
"local current current = redis.call('incr',KEYS[1]) if tonumber(current) == 1 then redis.call('expire', KEYS[1], 60) end");
script.setResultType(String.class);
List<String> keys = new ArrayList<>();
keys.add("callLimit");
this.template.execute(script, keys);
return true;
}
上面的代码将有效的QPS限制为 0.5/s ( 30/m).
其中为了避免race condition,将 incr 与 expire两个操作写到一个Lua脚本中实现原子性。
"local current current = redis.call('incr',KEYS[1]) if tonumber(current) == 1 then redis.call('expire', KEYS[1], 60) end"
转自:https://blog.csdn.net/qijin2016/article/details/79284553
两个简单的API限流实现方案的更多相关文章
- 服务接口API限流 Rate Limit 续
一.前言 上一篇文章中粗浅的介绍使用Redis和基于令牌桶算法进行对服务接口API限流,本文介绍另一种算法---漏桶算法的应用.Nginx想必大家都有所了解是一个高性能的 HTTP 和反向代理服务器, ...
- Springboot中使用redis进行api限流
api限流的场景 限流的需求出现在许多常见的场景中 秒杀活动,有人使用软件恶意刷单抢货,需要限流防止机器参与活动 某api被各式各样系统广泛调用,严重消耗网络.内存等资源,需要合理限流 淘宝获取ip所 ...
- AspNetCore添加API限流
最近发现有客户在大量的请求我们的接口,出于性能考虑遂添加了请求频率限制. 由于我们接口请求的是.Net Core写的API网关,所以可以直接添加一个中间件,中间件中使用请求的地址当key,通过配置中心 ...
- 服务接口API限流 Rate Limit
一.场景描述 很多做服务接口的人或多或少的遇到这样的场景,由于业务应用系统的负载能力有限,为了防止非预期的请求对系统压力过大而拖垮业务应用系统. 也就是面对大流量时,如何进行流量控制? 服务接口的流量 ...
- java 服务接口API限流 Rate Limit
一.场景描述 很多做服务接口的人或多或少的遇到这样的场景,由于业务应用系统的负载能力有限,为了防止非预期的请求对系统压力过大而拖垮业务应用系统. 也就是面对大流量时,如何进行流量控制? 服务接口的流量 ...
- Guava RateLimiter实现接口API限流
一.简介 Guava提供的RateLimiter可以限制物理或逻辑资源的被访问速率.RateLimit二的原理类似与令牌桶,它主要由许可发出的速率来定义,如果没有额外的配置,许可证将按每秒许可证规定的 ...
- redis实现api限流
redis官方给出了参考文档:INCR 这里参考第一种方法,使用token bucket实现:每个用户每秒有一个Counter: func RateLimiter(uid string, rlType ...
- 令牌桶算法实现API限流
令牌桶算法( Token Bucket )和 Leaky Bucket 效果一样但方向相反的算法,更加容易理解.随着时间流逝,系统会按恒定 1/QPS 时间间隔(如果 QPS=100 ,则间隔是 10 ...
- 【Dnc.Api.Throttle】适用于.Net Core WebApi接口限流框架
Dnc.Api.Throttle 适用于Dot Net Core的WebApi接口限流框架 使用Dnc.Api.Throttle可以使您轻松实现WebApi接口的限流管理.Dnc.Api.Thr ...
随机推荐
- Java中泛型Class<T>、T与Class<?>
一.区别 单独的T 代表一个类型 ,而 Class<T>代表这个类型所对应的类, Class<?>表示类型不确定的类 E - Element (在集合中使用,因为集合中存放的是 ...
- android 应用程序中执行Linux 命令
ADB 无线调试命令son = "setprop service.adb.tcp.port 5555\n" + "stop adbd\n" + "st ...
- Problem C: 默认参数:求圆面积
Description 编写一个带默认值的函数,用于求圆面积.其原型为: double area(double r=1.0); 当调用函数时指定参数r,则求半径为r的圆的面积:否则求半径为1的圆面积. ...
- django中scrf的实现机制
第一步:django第一次响应来自某个客户端的请求时,后端随机产生一个token值,把这个token保存在SESSION状态中,后端把这个token放到cookie中交给前端页面. 第二步:下次前端需 ...
- ubantu-vim操作
vim其实就是vi的升级版,vi里的所有命令vim里都可以用,一般使用来说几乎没什么差别. 注:本篇文章区分大小写! vi / vim三级模式的关系: 命令行模式 任何时候,不管用户处于何种模式,只要 ...
- python day05作业
- c++下基于windows socket的多线程服务器(基于TCP协议)
之前用c++实现过基于windows socket的单线程TCP服务器(http://www.cnblogs.com/jzincnblogs/p/5170230.html),今天实现了一个多线程的版本 ...
- 排序jq
var arr = [1,2,3,4,5,6,7]; arr.sort(function (a, b) { 从大到小 if (a > b) { return 1; } else if (a &l ...
- PAT乙级 1031. 查验身份证(15)
题目传送:https://www.patest.cn/contests/pat-b-practise/1031 一个合法的身份证号码由17位地区.日期编号和顺序编号加1位校验码组成.校验码的计算规则如 ...
- Spring Boot 揭秘与实战(一) 快速上手
文章目录 1. 简介 1.1. 什么是Spring Boot 1.2. 为什么选择Spring Boot 2. 相关知识 2.1. Spring Boot的spring-boot-starter 2. ...