一、前言

一篇文章中粗浅的介绍使用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. ado.net的5个主要对象

    connection 连接对象 command 命令对象,指示要执行的命令和存储过程! datareader是一个向前的只读的数据流. dataadapter是功能强大的适陪器,支持增删改查的功能 d ...

  2. PF_RING 总结

    1.背景 目前收包存在的问题: 第一:inpterrupt livelock, 当收到包的时候,网卡驱动程序就会产生一次中断.在大流量的情况下,操作系统将花费大量时间用于处理中断,而只有 少量的时间用 ...

  3. C++经典书籍推荐

    <C++程序设计语言> <C++语言设计与演化> <C++标准程序库> <EFFECTIVE C++ 中文版> <MORE EFFECTIVE C ...

  4. MIFARE系列1《MIFARE简介》

    随着社会的发展,智能卡在很多领域得到了广泛的应用.特别是非接触卡,由于使用方便以及功能强大的特点,在管理.公交.工作证.身份识别等领域得到了快速的普及和推广. 非接触卡已经逐步发展成为一个独立的跨学科 ...

  5. hdu 2822 Dogs

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=2822 Dogs Description Prairie dog comes again! Someda ...

  6. ajax 无刷新文件上传

    无废话,直接重点: 1:准备工作  需要4个js库 1.jquery 8以上版本 2.jquery.ui.widget.js 3.jquery.iframe-transport.js 4.jquery ...

  7. Entity Framework 泛型使用

    因为增删改查是我们常用到的方法,我们不可能每个数据模型都去完成增删改查,这样的办法太笨拙了.我们可以写个父类(包含增删改查),然后让所有的数据模型类继承该父类.那就要求我们的父类必须使用泛型来实现. ...

  8. 路由设置 windows

    打印路由信息: route print 如何临时添加电脑内部路由[ route add 网段 mask 子网掩码 网关] 例如:route add 172.18.0.0 mask 255.255.0. ...

  9. 骇客(Hacker)用语

                     什么是TCP/IP 是一种网络通信协议,他规范了网络上所有的通信设备,尤其是一个主机与另一个主机之间的数据往来格式以及传送方式.,TCP/IP是INTERNET的基础 ...

  10. camera render texture 游戏里的监控视角

    Camera里: 新建render texture并拖入到target texture里 新建材质球 拖入render texture      camera里的视角会在材质球上出现  新建一个pla ...