一、前言

一篇文章中粗浅的介绍使用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. JavaWeb之Servlet:Cookie 和 Session

    会话 现实生活中我们会用手机跟对方对话,拿起手机,拨号,然后对面接听,跟着互相通话,最后会话结束. 这个过程也可以用我们的B/S模式来描述: 打开浏览器—>输入地址->发出请求->服 ...

  2. Android体系结构

    由图可知,android被分成4个层次,以linux为核心,针对手机进行专门的优化,提供了android操作系统最基本的功能,在此之上又分为android runtime和libraries.其中Da ...

  3. 每日一练--C语言--串

    目标 实现串的经典模式匹配算法与KMP算法. 简述 自定义串结构: 串采用定长顺序存储结构,串从下标1开始存储,0下标存储串的实际长度: 匹配成功返回匹配位置,匹配失败返回0. #include &l ...

  4. Oracle Database Links解析

    什么是Database Links呢? 首先我们阐述下它的作用:使用户可以通过一个数据库访问到另外一个远程数据库. 那么Database Link是存储着远程数据库的连接信息. 如下图所示: 用户Sc ...

  5. Oracle出现字符集问题处理方法

    1.  Cmd进去DOS 2.  再输入dbca(database  create) 3.  弹出的界面,直接下一步,选择删除数据库 4.  成功删除后,回到一第一界面,选择创建数据库,下一步. 5. ...

  6. 【ExtJs】使用Cookie、切换主题和语言

    转自:http://witmax.cn/extjs-cookie-theme-lang.html 使用Cookie:   1 2 3 Ext.state.Manager.setProvider(new ...

  7. MVC4.0 WebApi如何自定义返回数据类型

    1.客户端可以通过HTTP Accept消息头来通知服务器客户端想要什么样的MIME类型数据,例如:application/json则代表告诉服务器想要的是Json数据 2.服务器端撇开客户端的请求类 ...

  8. 整理了一下 jQuery 的原型关系图,理解起来更加方便一些。

    图例:黄色的为对象,蓝色的为函数.

  9. What is the difference between position: static,relative,absolute,fixed

    What is the difference between static,relative, absolute,fixed we can refer to this link: expand

  10. web安全之token

    Token,就是令牌,最大的特点就是随机性,不可预测.一般黑客或软件无法猜测出来. 那么,Token有什么作用?又是什么原理呢? Token一般用在两个地方: 1)防止表单重复提交. 2)anti c ...