系统调优

EMQX 自 4.2 版本以来,在一台 8 核心、32G 内存的 CentOS 服务器上,MQTT 连接压力测试可达到 130 万。

100 万连接测试所需的 Linux 内核参数,网络协议栈参数,Erlang 虚拟机参数, EMQX 消息服务器参数设置如下:

Linux 操作系统参数

系统全局允许分配的最大文件句柄数:

  1. # 2 millions system-wide
  2. sysctl -w fs.file-max=2097152
  3. sysctl -w fs.nr_open=2097152
  4. echo 2097152 > /proc/sys/fs/nr_open

允许当前会话 / 进程打开文件句柄数:

  1. ulimit -n 1048576

/etc/sysctl.conf

持久化 ‘fs.file-max’ 设置到 /etc/sysctl.conf 文件:

  1. fs.file-max = 1048576

/etc/systemd/system.conf 设置服务最大文件句柄数:

  1. DefaultLimitNOFILE=1048576

/etc/security/limits.conf

/etc/security/limits.conf 持久化设置允许用户 / 进程打开文件句柄数:

  1. * soft nofile 1048576
  2. * hard nofile 1048576

TCP 协议栈网络参数

并发连接 backlog 设置:

  1. sysctl -w net.core.somaxconn=32768
  2. sysctl -w net.ipv4.tcp_max_syn_backlog=16384
  3. sysctl -w net.core.netdev_max_backlog=16384

可用知名端口范围:

  1. sysctl -w net.ipv4.ip_local_port_range='1000 65535'

TCP Socket 读写 Buffer 设置:

  1. sysctl -w net.core.rmem_default=262144
  2. sysctl -w net.core.wmem_default=262144
  3. sysctl -w net.core.rmem_max=16777216
  4. sysctl -w net.core.wmem_max=16777216
  5. sysctl -w net.core.optmem_max=16777216
  6. #sysctl -w net.ipv4.tcp_mem='16777216 16777216 16777216'
  7. sysctl -w net.ipv4.tcp_rmem='1024 4096 16777216'
  8. sysctl -w net.ipv4.tcp_wmem='1024 4096 16777216'

TCP 连接追踪设置:

  1. sysctl -w net.netfilter.nf_conntrack_max=1000000
  2. sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=30

TIME-WAIT Socket 最大数量、回收与重用设置:

  1. sysctl -w net.ipv4.tcp_max_tw_buckets=1048576
  2. # 注意:不建议开启该设置,NAT 模式下可能引起连接 RST
  3. # sysctl -w net.ipv4.tcp_tw_recycle=1
  4. # sysctl -w net.ipv4.tcp_tw_reuse=1

FIN-WAIT-2 Socket 超时设置:

  1. sysctl -w net.ipv4.tcp_fin_timeout=15

Erlang 虚拟机参数

优化设置 Erlang 虚拟机启动参数,配置文件 emqx/etc/emqx.conf:

  1. ## Erlang Process Limit
  2. node.process_limit = 2097152
  3. ## Sets the maximum number of simultaneously existing ports for this system
  4. node.max_ports = 1048576

docker 参数调优

通常调优应该在docker的主机上做,但是如果一定要从docker内部做,可以参考如下例子:

  1. docker run -d --name emqx -p 18083:18083 -p 1883:1883 -p 4369:4369 \
  2. --sysctl fs.file-max=2097152 \
  3. --sysctl fs.nr_open=2097152 \
  4. --sysctl net.core.somaxconn=32768 \
  5. --sysctl net.ipv4.tcp_max_syn_backlog=16384 \
  6. --sysctl net.core.netdev_max_backlog=16384 \
  7. --sysctl net.ipv4.ip_local_port_range=1000 65535 \
  8. --sysctl net.core.rmem_default=262144 \
  9. --sysctl net.core.wmem_default=262144 \
  10. --sysctl net.core.rmem_max=16777216 \
  11. --sysctl net.core.wmem_max=16777216 \
  12. --sysctl net.core.optmem_max=16777216 \
  13. --sysctl net.ipv4.tcp_rmem=1024 4096 16777216 \
  14. --sysctl net.ipv4.tcp_wmem=1024 4096 16777216 \
  15. --sysctl net.ipv4.tcp_max_tw_buckets=1048576 \
  16. --sysctl net.ipv4.tcp_fin_timeout=15 \
  17. emqx/emqx:latest

::: 友情提示 不要使用 --privileged 或者将系统内核目录挂载到docker中进行调优。 :::

EMQX 消息服务器参数

ceptor 池大小,最大允许连接数。 emqx/etc/emqx.conf emqx/etc/listeners.conf }

  1. ## TCP Listener
  2. listener.tcp.external = 0.0.0.0:1883
  3. listener.tcp.external.acceptors = 64
  4. listener.tcp.external.max_connections = 1024000

测试客户端设置

测试客户端服务器在一个接口上,最多只能创建 65000 连接:

  1. sysctl -w net.ipv4.ip_local_port_range="500 65535"
  2. echo 1000000 > /proc/sys/fs/nr_open
  3. ulimit -n 100000

emqtt_bench

并发连接测试工具: http://github.com/emqx/emqtt_bench系统调优 - 图1 (opens new window)