我有一台装有 Erlang 应用程序的 Linux 服务器,它显示了一个奇怪的限制,即最大 TCP 传入连接数恰好为 65536。
Erlang 应用程序是使用 Cowboy 框架编写的。
我已经通过以下方式调整了内核参数:
/etc/sysctl.conf:
# Increase system file descriptor limit
fs.file-max = 300000
# Discourage Linux from swapping idle processes to disk (default = 60)
vm.swappiness = 10
# Increase Linux autotuning TCP buffer limits
# Set max to 16MB for 1GE and 32M (33554432) or 54M (56623104) for 10GE
# Don't set tcp_mem itself! Let the kernel scale it based on RAM.
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
net.core.optmem_max = 40960
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# Make room for more TIME_WAIT sockets due to more clients,
# and allow them to be reused if we run out of sockets
# Also increase the max packet backlog
net.core.netdev_max_backlog = 50000
net.ipv4.tcp_max_syn_backlog = 30000
net.ipv4.tcp_max_tw_buckets = 2000000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 10
# Disable TCP slow start on idle connections
net.ipv4.tcp_slow_start_after_idle = 0
# Disable source routing and redirects
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
# Log packets with impossible addresses for security
net.ipv4.conf.all.log_martians = 1
/etc/security/limits.conf:
* soft nofile 300000
* hard nofile 300000
我还检查了 Erlang 进程的最大数量,但它似乎不是限制因素:
1> erlang:system_info(process_limit).
262144
测试连接由来自 4 个不同 IP 地址的 4 台客户端机器建立(因此不存在客户端限制的问题),初始身份验证之后,连接处于空闲状态,因此服务器 CPU 利用率低于 50%,内存利用率也低于 35%。
编辑:我不确定这是否重要:Erlang 服务器应用程序正在监听端口 8000,我使用以下 iptables 规则让它也监听端口 80:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8000
我还应该研究什么来消除 65536 个连接的限制?
答案1
检查您的应用程序是如何编码的。端口限制为 65535,并且 0-1024 范围内的端口是保留的。
如果您的应用程序使用临时端口;来自 RFC-6056
- 临时端口
2.1. 传统临时端口范围
互联网号码分配机构 (IANA) 负责分配
互联网工程任务组 (IETF) 开发的协议中使用的唯一参数和值
,包括知名端口 [IANA]。IANA保留了以下 TCP 和 UDP
16 位端口范围的使用:o 知名端口,0 到 1023。
o 注册端口,1024 至 49151
o 动态和/或私有端口,49152 至 65535
IANA 定义的动态端口范围由 49152-65535 范围组成,用于选择临时端口。
在最后一步,询问供应商这是否是硬编码值。(int_16)
答案2
如果您的 4 个不同的客户端从同一主机连接到服务器,则您不能同时拥有超过 65536 个活动的传入连接,因为您只能为相同的传入 IP 地址生成 65536 个端口。
答案3
查看 dmesg 输出后我发现了问题:
nf_conntrack: table full, dropping packet
因此问题出在使用 iptables 的 TCP 重定向 80 => 8000 中。
我删除了该 iptables 规则,并让 Erlang 直接监听 80 和 8000 两个端口,65k 的限制就被取消了。