限制并发连接数

因为某特殊需求,要对客户端的连接作出限制,例如某端口的全局并发访问数不能超过2个。根据个人所掌握知识,可以从两方面入手:防火墙和nginx接入层。

防火墙

iptables
connlimit
模块可限制 全局
的并发连接数。其用法如下:

iptables -I INPUT -p tcp --syn --dport 8081 -m connlimit --connlimit-above 2 --connlimit-mask 0 -j DROP

命令要点:

  1. -p tcp
    :针对 tcp
    协议过滤;
  2. --dport 8081
    :对 8081
    端口起作用;
  3. -m connlimit
    :使用 connlimit
    模块
  4. --connlimit-above 2
    :最多不超过2个并发连接
  5. --connlimit-mask 0
    : 默认ip掩码是32,即限制单ip并发连接数,设置为0则限制全局连接。

用上述命令配置好防火墙后,可用以下方法测试效果:

  1. nc
    监听端口: nc -l 8081 -k
    ;
  2. 打开另外几个终端,测试连接: nc localhost 8081

正确配置情形下,第一个和第二个 nc
连接是正常的,第三个连接起会出现 broken pipe
错误,即无法连接,说明防火墙达到了预期效果(也可以用 netstat -nt | grep 8081
查看已建立连接)。

Nginx

限制速率和并发连接数, Nginx
最好用的当属 limit_conn
模块。对应 http
tcp
协议,分别有 ngx_http_limit_conn_module
ngx_stream_conn_module
两个模块,两者配置语法上基本相同,下文以 http
协议讲述配置。

首先我们在 http
块重创建一个共享存储区 limit_conn_zone
,指定key和共享内存大小:

http {
    limit_conn_zone $server_name zone=servers:10m;
    ....
}

两个注意点:

  1. 指定的key值是 $server_name
    ,针对 主机域名
    的并发连接作出限制;如果只是限制单个ip的并发连接数,可用 $binary_remote_addr
    ;其他可用的值请参考 http://nginx.org/en/docs/http/ngx_http_core_module.html#variables
  2. 共享存储区的名称为 servers
    ,大小是 10m
    ,可以根据需要更改。

接下来我们在 server
或者 location
块中限制并发访问数:

server {
    limit_conn servers 2;
    ...
}

配置中的 servers
就是 http
块中配置的共享存储区名称。
效果验证请参考”防火墙”一节。

参考

  1. https://serverfault.com/questions/699620/linux-limit-connections-on-a-specific-port
  2. http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html