一、前言

一篇文章中粗浅的介绍使用Redis和基于令牌桶算法进行对服务接口API限流,本文介绍另一种算法---漏桶算法的应用。Nginx想必大家都有所了解是一个高性能的 HTTP 和反向代理服务器,优秀而强大的Nginx依然可以处理限制来自单个IP地址的请求处理频率。ngx_http_limit_conn_module模块可以限制请求数即通过定义的键值来限制请求处理的频率。该模块其采用漏桶算法,每秒固定处理请求数,推迟延迟请求。

二、ngx_http_limit_conn_module模块指令

  • limit_req_zone

语法: limit_req_zone $variable zone=name:size rate=rate;
        默认值: none
        配置段: http

说明:设置一块共享内存限制域用来保存键值的状态参数,尤其是保存了当前超出请求的数量。键的值就是指定的变量(空值不会被计算)。如:

limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;

区域名称为one,大小为10m,平均处理的请求频率不能超过每秒一次。
键值是客户端IP。

使用$binary_remote_addr变量,可以将每条状态记录大小减小到64字节,十六万多条记录。

如果共享内存限制域的存储空间耗尽了,对于后续的所有请求,nginx都会返回503错误。

速度可以设置为每秒处理请求数或每分钟处理请求数,其值必须是整数。

  • limit_req_log_level

语法: limit_req_log_level info | notice | warn | error;
  默认值: limit_req_log_level error;
  配置段: http, server, location

说明:设置你所希望的日志级别,当服务器因为频率过高拒绝或者延迟处理请求时可以记下相应级别的日志。 延迟记录的日志级别比拒绝的低一个级别;比如, 如果设置“limit_req_log_level notice”, 延迟的日志就是info级别。

  • limit_req_status

语法: limit_req_status code
        默认值: limit_req_status 503
        配置段: http, server, location

说明:设置拒绝请求的响应状态码。

  • limit_req

语法: limit_req zone=name [burst=number] [nodelay];
        默认值: —
        配置段: http, server, location

说明:设置对应的共享内存限制域和允许被处理的最大请求数阈值。 如果请求的频率超过了限制域配置的值,请求处理会被延迟,所以所有的请求都是以定义的频率被处理的。 超过频率限制的请求会被延迟,直到被延迟的请求数超过了定义的阈值,这时,这个请求会被终止,并返回503 (Service Temporarily Unavailable) 错误。这个阈值的默认值为0。如:

limit_req_zone $binary_remote_addr zone=ttlsa_com:10m rate=5r/s;
server {
location /www.cnblogs.com/ {
limit_req zone=cnblogs_com burst=;
}
}

限制平均每秒不超过5个请求,同时允许超过频率限制的请求数不多于5个。
      如果不希望超过的请求被延迟,可以用nodelay参数,如:

limit_req zone=ttlsa_com burst= nodelay;

完整的配置

http {
limit_req_zone $binary_remote_addr zone=cnblogs_com:10m rate=1r/s; server {
location /www.cnblogs.com/ {
limit_req zone=cnblogs_com burst=;
}
}
}

从上述的配置中,可以看出对所有的IP都进行了限制。在某些特殊情况下,我们不希望对某些IP限制如公司IP,那么白名单就有了用武之地,将不需要限制的IP加入到白名单中即可。白名单实现方法,需要结合geo和map指令来实现。看配置:

geo $whiteiplist  {
default ;
127.0.0.1 ;
10.0.0.0/ ;
107.155.42.0/ ;
} map $whiteiplist $limit {
$binary_remote_addr;
"";
} limit_conn_zone $limit zone=limit:10m; server {
listen ;
server_name www.cnblogs.com; location ^~ /cnblogs.com/ {
limit_conn limit ;
limit_rate 200k;
}
}
}

说明:

1. geo指令定义一个白名单$whiteiplist, 默认值为1, 所有都受限制。 如果客户端IP与白名单列出的IP相匹配,则$whiteiplist值为0也就是不受限制。
2. map指令是将$whiteiplist值为1的,也就是受限制的IP,映射为客户端IP。将$whiteiplist值为0的,也就是白名单IP,映射为空的字符串。
3. limit_conn_zone和limit_req_zone指令对于键为空值的将会被忽略,从而实现对于列出来的IP不做限制。

三、题外话

对于肆无忌惮的蜘蛛或者大流量恶意的攻击访问,会带来带宽的浪费和服务器巨大的压力,影响业务的正常使用。

对于这些情况可以采取多种措施:

1、对同一个ip的连接数,并发数和请求书进行限制。

通过ngx_http_limit_conn_module和ngx_http_limit_conn_module模块可以很好的达到效果。

上周玩客被百度蜘蛛给盯上了,百度蜘蛛对玩客的抓取频率增加了5倍。百度蜘蛛抓取量骤增,导致服务器负载很高。最终用nginx的ngx_http_limit_req_module模块限制了百度蜘蛛的抓取频率。每分钟允许百度蜘蛛抓取200次,多余的抓取请求返回503。

nginx的配置:
#全局配置
limit_req_zone $anti_spider zone=anti_spider:60m rate=200r/m;
#某个server中
limit_req zone=anti_spider burst=5 nodelay;
if ($http_user_agent ~* “baiduspider”) {
set $anti_spider $http_user_agent;
}

参数说明:
指令linit_req_zone 中的rate=200r/m 表示每分钟只能处理200个请求。
指令limit_req 中的burst=5 表示最大并发为5。即同一时间只能同时处理5个请求。
指令limit_req 中的 nodelay 表示当已经达到burst值时,再来新请求时,直接返回503
IF部分用于判断是否是百度蜘蛛的user agent。如果是,就对变量$anti_spider赋值。这样就做到了只对百度蜘蛛进行限制了。

2、对恶意的IP访问攻击

首先要将恶意的IP挡在缓存之外,减小穿透缓存把压力打到DB上。

其次对于的恶意的IP进行封IP甚至封IP段。

ngx_http_access_module模块中的deny和allow指令

allow
语法:  allow address | CIDR | unix: | all;
默认值: —
配置段: http, server, location, limit_except

允许某个ip或者一个ip段访问.如果指定unix:,那将允许socket的访问.注意:unix在1.5.1中新加入的功能,如果你的版本比这个低,请不要使用这个方法。

deny
语法:  deny address | CIDR | unix: | all;
默认值: —
配置段:http, server, location, limit_except

禁止某个ip或者一个ip段访问.如果指定unix:,那将禁止socket的访问.注意:unix在1.5.1中新加入的功能,如果你的版本比这个低,请不要使用这个方法。

location / {
deny  107.155.42.59;
allow 107.155.42.60/66;
deny  all;
}

从上到下的顺序,匹配到了便跳出。如上的例子先禁止了107.155.42.59,接下来允许了1个网段,最后未匹配的IP全部禁止访问。在实际生产环境中,我们也会使用nginx 的geo模块配合使用。

deny和allow是nginx里面最基本的指令,如果想禁止谁访问就添加指令deny加上IP,想允许则加上指令allow ip;如果想禁止或者允许所有,那么allow all或者deny all即可。

参考:

http://www.bo56.com/%E4%BD%BF%E7%94%A8nginx%E9%99%90%E5%88%B6%E7%99%BE%E5%BA%A6%E8%9C%98%E8%9B%9B%E7%9A%84%E9%A2%91%E7%B9%81%E6%8A%93%E5%8F%96/

由于本人经验有限,文章中难免会有错误,请浏览文章的您指正或有不同的观点共同探讨!

服务接口API限流 Rate Limit 续的更多相关文章

  1. 服务接口API限流 Rate Limit

    一.场景描述 很多做服务接口的人或多或少的遇到这样的场景,由于业务应用系统的负载能力有限,为了防止非预期的请求对系统压力过大而拖垮业务应用系统. 也就是面对大流量时,如何进行流量控制? 服务接口的流量 ...

  2. java 服务接口API限流 Rate Limit

    一.场景描述 很多做服务接口的人或多或少的遇到这样的场景,由于业务应用系统的负载能力有限,为了防止非预期的请求对系统压力过大而拖垮业务应用系统. 也就是面对大流量时,如何进行流量控制? 服务接口的流量 ...

  3. Guava RateLimiter实现接口API限流

    一.简介 Guava提供的RateLimiter可以限制物理或逻辑资源的被访问速率.RateLimit二的原理类似与令牌桶,它主要由许可发出的速率来定义,如果没有额外的配置,许可证将按每秒许可证规定的 ...

  4. Spring Cloud微服务Sentinel+Apollo限流、熔断实战总结

    在Spring Cloud微服务体系中,由于限流熔断组件Hystrix开源版本不在维护,因此国内不少有类似需求的公司已经将眼光转向阿里开源的Sentinel框架.而以下要介绍的正是作者最近两个月的真实 ...

  5. AspNetCore添加API限流

    最近发现有客户在大量的请求我们的接口,出于性能考虑遂添加了请求频率限制. 由于我们接口请求的是.Net Core写的API网关,所以可以直接添加一个中间件,中间件中使用请求的地址当key,通过配置中心 ...

  6. Hystrix介绍以及服务的降级限流熔断

    (dubbo熔断,Hystrix问的少) 无论是缓存层还是存储层都会有出错的概率,可以将它们视同为资源.作为并发量较大的系统,假如有一个资源不可用,可能会造成线程全部 hang (挂起)在这个资源上, ...

  7. Google Guava缓存实现接口的限流

    一.项目背景 最近项目中需要进行接口保护,防止高并发的情况把系统搞崩,因此需要对一个查询接口进行限流,主要的目的就是限制单位时间内请求此查询的次数,例如1000次,来保护接口. 参考了 开涛的博客聊聊 ...

  8. Springboot中使用redis进行api限流

    api限流的场景 限流的需求出现在许多常见的场景中 秒杀活动,有人使用软件恶意刷单抢货,需要限流防止机器参与活动 某api被各式各样系统广泛调用,严重消耗网络.内存等资源,需要合理限流 淘宝获取ip所 ...

  9. 引擎基本服务接口API介绍

    Slickflow.NET 开源工作流引擎基础介绍(一) -- 引擎基本服务接口API介绍 https://www.cnblogs.com/slickflow/p/4807227.html 工作流术语 ...

随机推荐

  1. MIFARE系列6《射频卡与读写器的通讯》

    1. 复位应答(Answer to request) 读写器呼叫磁场内的卡片,卡片对呼叫做出应答.对刚进入磁场得到电复位处于休闲状态的卡片,卡请求(REQA,0x26):对于已进行过读写操作并进入休眠 ...

  2. linux kernel 0.11 bootsect

    bootsect作用 ①将自己移动到0x90000处 ②将setup从磁盘读到0x90200处 ③将system从磁盘读到0x10000处 寄存器 汇编代码中存在:数据段data seg 栈段 sta ...

  3. 分享C#原生ID(流水号)生成功能实现

    ///, , )).TotalMilliseconds.ToString(")); /// <summary>         ///         /// </summ ...

  4. linux 捕获信号处理中遇到的死锁

    tag: 信号 signal  sigchld  死锁 堆栈 我们的程序需要捕获信号自己处理,所以尝试对1-32的信号处理(后面33-64的信号不处理).但是在调试代码时,发现一个线程死锁的问题.程序 ...

  5. libevent I/O示例

    I/O示例使用一个windows平台上服务器/客户端的例子来演示.由于为了减少代码篇幅等各种由于本人懒而产生的原因,以下代码没有做错误处理以及有些小问题,但是我想应该不影响演示,大家多包涵. 服务器代 ...

  6. iOS-打包成ipa

    第一步:模拟器选择栏,选择"Generic iOS Device ".早期版本需要断开手机连接,才可以找到. 第二步:选择"Product"菜单下的" ...

  7. HTML5-地理定位

    HTML5 Geolocation(地理定位)用于定位用户的位置. 定位用户的位置 HTML5 Geolocation API 用于获得用户的地理位置. 鉴于该特性可能侵犯用户的隐私,除非用户同意,否 ...

  8. React + Reflux

    React + Reflux 渲染性能优化原理   作者:ManfredHu 链接:http://www.manfredhu.com/2016/11/08/23-reactRenderingPrinc ...

  9. 团队开发-极速蜗牛-NABC模型

    特点:益智,操作简单. N(need):手机小游戏,可以让大家打发无聊的时间,比如:排队打饭,课间休息,等公交等地铁,拿出手机玩玩小游戏. A(approach):基于光的反射原理,编写的小游戏. B ...

  10. php调用微信发送自定义模版接口

     function sendWechatmodel($openid,$data,$go_url)//接受消息的用户openid,发送的消息,点击详情跳转的url        {           ...