在当下互联网高并发时代中,项目往往会遇到需要限制客户端连接的需求。我们熟知的 Nginx 就提供了有这样的功能,可以简单的实现对客户端请求频率,并发连接和传输速度的限制….

Nginx 限流

Nginx为我们提供了请求限制模块(ngx_http_limit_req_module)、基于令牌桶算法的流量限制模块(ngx_stream_limit_conn_module),可以方便的控制令牌速率,自定义调节限流,实现基本的限流控制…

请求限制

请求限制的功能来自于 ngx_http_limit_req_module 模块。使用它需要首先在 http 配置段中定义限制的参照标准和状态缓存区大小。

limit_req_zone 只能配置在 http 范围内;

$binary_remote_addr 表示客户端请求的IP地址;

mylimit 自己定义的变量名;

rate 请求频率,每秒允许多少请求;

limit_req 与 limit_req_zone 对应,burst 表示缓存住的请求数,也就是任务队列。

下面的配置就是定义了使用客户端的 IP 作为参照依据,并使用一个 10M 大小的状态缓存区。结尾的 rate=1r/s 表示针对每个 IP 的请求每秒只接受一次。

10M 的状态缓存空间够不够用呢?官方给出的答案是 1M 的缓存空间可以在 32 位的系统中服务 3.2 万 IP 地址,在 64 位的系统中可以服务 1.6 万 IP 地址,所以需要自己看情况调整。如果状态缓存耗光,后面所有的请求都会收到 503(Service Temporarily Unavailable) 错误。

脚本代码

1
2
3
4
5
6
7
8
9
10
11
12
# 定义了一个 mylimit 缓冲区(容器),请求频率为每秒 1 个请求(nr/s)
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;
server {
listen 70;
location / {
# nodelay 不延迟处理
# burst 是配置超额处理,可简单理解为队列机制
# 上面配置同一个 IP 没秒只能发送一次请求(1r/s),这里配置了缓存3个请求,就意味着同一秒内只能允许 4 个任务响应成功,其它任务请求则失败(503错误)
limit_req zone=mylimit burst=3 nodelay;
proxy_pass http://localhost:7070;
}
}

测试代码

为了方便此处提供 JAVA、AB 两种测试代码..

1
2
3
# -n 即指定压力测试总共的执行次数
# -c 即指定的并发数
ab -n 5 -c 5 http://192.168.0.133:70/index
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.battcn.limiting;

import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* @author Levin
* @since 2018/7/27 0027
*/
public class NginxLimiterTest { public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService service = Executors.newFixedThreadPool(5);
for (int i = 0; i < 6; i++) {
CompletableFuture.supplyAsync(() -> {
final ResponseEntity<String> entity = new RestTemplate().getForEntity("http://192.168.0.133:70/index", String.class);
return entity.getBody();
}, service).thenAccept(System.out::println);
}
service.shutdown();
}
}

测试日志

此处提供 AB 测试结果 JAVA 的日志就不贴了,5个请求其中一个请求是有问题的,出问题的那个就是被拒绝请求的…

1
2
3
4
5
6
7
8
9
[root@localhost myconf]# ab -n 5 -c 5 http://192.168.0.133:70/index
Document Path: /index
Document Length: 34 bytes Concurrency Level: 5
Time taken for tests: 0.002 seconds
Complete requests: 5
Failed requests: 1
(Connect: 0, Receive: 0, Length: 1, Exceptions: 0)

并发限制

Nginx 并发限制的功能来自于 ngx_http_limit_conn_module 模块,跟请求配置一样,使用它之前,需要先定义参照标准和状态缓存区。

limit_conn_zone 只能配置在 http 范围内;

$binary_remote_addr 表示客户端请求的IP地址;

myconn 自己定义的变量名(缓冲区);

limit_rate 限制传输速度

limit_conn 与 limit_conn_zone 对应,限制网络连接数

下面的配置就是定义了使用客户端的 IP 作为参照依据,并使用一个 10M 大小的状态缓存区。限定了每个IP只允许建立一个请求连接,同时传输的速度最大为 1024KB

脚本代码

1
2
3
4
5
6
7
8
9
10
11
12
# 定义了一个 myconn 缓冲区(容器)
limit_conn_zone $binary_remote_addr zone=myconn:10m;
server {
listen 70;
location / {
# 每个 IP 只允许一个连接
limit_conn myconn 1;
# 限制传输速度(如果有N个并发连接,则是 N * limit_rate)
limit_rate 1024k;
proxy_pass http://localhost:7070;
}
}

说点什么

请求限流方面自己写一个简单的 Spring Boot 程序部署到服务器配置好 Nginx 映射即可,并发限流弄一个大文件下载,或者让自己服务接口在内部休眠一定时间就能测试出效果….

参考文献

利用 Nginx 实现限流的更多相关文章

  1. nginx的限流问题

    nginx的限流问题 http{ limit_req_zone $binary_remote_addr zone=req_one:10m rate=100r/s;server{ listen 8080 ...

  2. 【高并发】面试官问我如何使用Nginx实现限流,我如此回答轻松拿到了Offer!

    写在前面 最近,有不少读者说看了我的文章后,学到了很多知识,其实我本人听到后是非常开心的,自己写的东西能够为大家带来帮助,确实是一件值得高兴的事情.最近,也有不少小伙伴,看了我的文章后,顺利拿到了大厂 ...

  3. Nginx分片限流

    一.全局限流 在http节点中添加 # 创建限流规则 limit_req_zone $binary_remote_addr zone=addr:10m rate=1r/s;# 客户端进行限流 # li ...

  4. nginx限流&健康检查

    Nginx原生限流模块: ngx_http_limit_conn_module模块 根据前端请求域名或ip生成一个key,对于每个key对应的网络连接数进行限制. 配置如下: http模块   ser ...

  5. 死磕nginx系列--nginx 限流配置

    限流算法 令牌桶算法 算法思想是: 令牌以固定速率产生,并缓存到令牌桶中: 令牌桶放满时,多余的令牌被丢弃: 请求要消耗等比例的令牌才能被处理: 令牌不够时,请求被缓存. 漏桶算法 算法思想是: 水( ...

  6. 用nginx实现分布式限流

    1.前言 一般对外暴露的系统,在促销或者黑客攻击时会涌来大量的请求,为了保护系统不被瞬间到来的高并发流量给打垮, 就需要限流 . 本文主要阐述如何用nginx 来实现限流. 听说 Hystrix 也可 ...

  7. 【Nginx】实现负载均衡、限流、缓存、黑白名单和灰度发布,这是最全的一篇了!

    写在前面 在<[高并发]面试官问我如何使用Nginx实现限流,我如此回答轻松拿到了Offer!>一文中,我们主要介绍了如何使用Nginx进行限流,以避免系统被大流量压垮.除此之外,Ngin ...

  8. [转]Nginx限流配置

    原文:https://www.cnblogs.com/biglittleant/p/8979915.html 作者:biglittleant 1. 限流算法 1.1 令牌桶算法 算法思想是: 令牌以固 ...

  9. 最近学习了限流与RateLimiter

    前言 分布式环境下应对高并发保证服务稳定几招,按照个人理解,优先级从高到低分别为缓存.限流.降级.熔断,每招都有它的作用,本文重点就讲讲限流这部分. 坦白讲,其实上面的说法也不准确,因为服务降级.熔断 ...

随机推荐

  1. SQL Server账号密码(sa)登录失败 错误原因:233

    (其实以前经常用的时候,都很简单,最近一段时间不用了,再一看发现都忘记的差不多了,还是写一篇博客吧,防止下一次再在这种问题上面浪费时间) 右键此电脑,点击管理 如果没有此电脑打开文件夹 在这里右键也是 ...

  2. Linux 终止进程

    kill命令 kill -l,查看可用的进程号 支持64种,常用的三种,1代表重启,9代表强制终止,15代表正常终止 kill -1 进程ID号,重启进程 killall -9 进程名,杀死对应的全部 ...

  3. Windows下虚拟机Linux(CentOS8)扩容设置 - 磁盘扩容中的坑和解决方法

    摘要:[原创]转载请注明作者Johnthegreat和本文链接 由于虚拟机空间不足,为了避免重装虚拟机,做了一次无损扩容.   过程中的报错如下: [root@localhost ~]# pvcrea ...

  4. mysql基础之-mysql数据控制语言DCL(七)

    0x01 mysql中的权限分布 mysql中的用户信息都存储在系统数据库mysql的user表中 查询语句:select host,user,password from mysql.user; 创建 ...

  5. ElasticSearch系列(二):ElasticSearch Head、Kibana、Elasticsearch-Analysis-Ik安装、使用

    1.ElasticSearch Head使用 扩展程序安装插件:ElasticSearch github地址:https://github.com/mobz/elasticsearch-head/ 运 ...

  6. laravel表单中文错误提示本地化

    <?php return [ /* |-------------------------------------------------------------------------- | V ...

  7. Linux防火墙iptables详解

    iptables详解(思维导图) 1. 概述 1.1 iptable简介 1.2 防火墙的种类 1.3 netfilter 2. iptables的工作流程 2.1 iptables工作图示 2.2 ...

  8. FWT,FST入门

    0.目录 目录 0.目录 1.什么是 FWT 2. FWT 怎么做 2.1. 或卷积 2.2.与卷积 2.3.异或卷积 2.4.例题 3. FST 3.1. FST 怎么做 3.2.例题 1.什么是 ...

  9. ca12a_c++顺序容器的操作5_访问容器中的数据元素

    ca12a_c++顺序容器的操作5_访问容器中的数据元素访问元素:c.back()..显示最后一个数据c.front() ..显示第一个数据c[n],n就是下标,适合vector与dequec.at( ...

  10. vs.net/vscode中使用Beetlex创建vue应用

    平时在开发Vue应用则需要安装nodejs,vue cli等相关东西相对来说麻烦一些:如果你喜欢像vs.net/vscode创建普通项目一样就能开发Vue项目的话那可以尝试一下BeetleX针对Vue ...