Skip to main content

Command Palette

Search for a command to run...

解决EMQX服务每过几个小时崩溃crash

Updated
2 min read
H

I am ZhangSan, a mere nobody. 我是张三,一个无名小子。

问题场景

服务稳定运行一年多了,最近几天,每过几个小时就会发生crash,服务挂掉。

查看日志,有提示:[warning] Ranch acceptor reducing accept rate: out of file descriptors

大概是说文件描述符不足,这里需要按照文档来进行系统调优。机器安装时都是默认的,文件描述符 ulimit -n 查看为默认的 65536

💡
官方系统调优文档:系统调优 | EMQX文档

关键项为调整系统文件描述符,承载量大的话要多节点来组建集群

Linux 操作系统参数

sysctl

以下内核级参数严格按照官方文档编写,脚本将参数单独写入 /etc/sysctl.d/99-emqx-performance.conf 文件,方便系统直接载入和删除。更新于2025-10-30

sudo tee /etc/sysctl.d/99-emqx-performance.conf > /dev/null <<'EOF'
# EMQX 官方性能调优 - 2025-10
# https://docs.emqx.com/zh/emqx/latest/performance/tune.html

# 内核级最大文件句柄数
fs.file-max                                      = 2097152
# 单个进程最大文件描述符
fs.nr_open                                       = 2097152

# 并发连接 backlog 设置
net.core.somaxconn                               = 32768
net.ipv4.tcp_max_syn_backlog                     = 16384
net.core.netdev_max_backlog                      = 16384

# 可用知名端口范围
net.ipv4.ip_local_port_range                     = 1024 65535

# TCP Socket 读写 Buffer 设置
net.core.rmem_default                            = 262144
net.core.wmem_default                            = 262144
net.core.rmem_max                                = 16777216
net.core.wmem_max                                = 16777216
net.core.optmem_max                              = 16777216

net.ipv4.tcp_rmem                                = 4096 16384 16777216
net.ipv4.tcp_wmem                                = 4096 16384 16777216

# TCP 连接追踪设置
net.nf_conntrack_max                             = 1000000
net.netfilter.nf_conntrack_max                   = 1000000
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 30

# TIME-WAIT Socket 最大数量、回收与重用设置
net.ipv4.tcp_max_tw_buckets                      = 1048576

# 注意:不建议开启該设置,NAT 模式下可能引起连接 RST
# net.ipv4.tcp_tw_recycle                        = 1
# net.ipv4.tcp_tw_reuse                          = 1

# FIN-WAIT-2 Socket 超时设置
net.ipv4.tcp_fin_timeout                         = 15
EOF

立即加载无需重启

sudo sysctl -p /etc/sysctl.d/99-emqx-performance.conf

最后检查并修改 emqx.conf 的相应参数

## 设置 Erlang 系统同时存在的最大端口数
node.max_ports = 2097152

## TCP 监听器配置
listeners.tcp.default.acceptors = 64
listeners.tcp.default.max_connections = 1024000

以下为官方原文档摘录

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

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

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

ulimit -n 1048576

/etc/sysctl.conf

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

fs.file-max = 1048576

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

DefaultLimitNOFILE=1048576

/etc/security/limits.conf

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

* soft nofile 1048576
* hard nofile 1048576

TCP 协议栈网络参数

并发连接 backlog 设置:

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

More from this blog

git切换分支缓慢问题

背景 最近在项目中 test 分支与 master 分支切换时感到非常慢,大概需要1-2分钟 解决 找出两个分支的最大的差异 # 找出两个分支的差异 git diff --dirstat=files master..test # 输出 98.7% vendor/alipaysdk/openapi/v2/aop/request/ 分别检出两个分支到不同目录,经过比较发现文件主要差异为行尾表现不同,master 分支的文件为 LF、test 分支的为 CRLF。 处理方案 使用 .gitatt...

Feb 10, 20261 min read7

软件生产范式: 从 Ddd 到 Sdd + Tdd 的未来之路

未来的软件系统,很可能不再依赖大量手写的代码,而是依赖可验证的业务规范,以及对这些规范的自动化实现。——这正是从 DDD → SDD + TDD 的演进方向。 在 AI 深度参与软件开发的时代,传统的代码中心开发方式正在加速老化。我们正在经历一次结构性转变:从“写代码”转向“写规范 + 写测试 + 让 AI 自动补全逻辑”。 这篇文章试图提供一个前瞻性的观点(深度使用 vibe coding 近

Dec 9, 20253 min read21
软件生产范式: 从 Ddd 到 Sdd + Tdd 的未来之路

多项目部署时使用不同node版本与包管理器

nvm 项目地址:https://github.com/nvm-sh/nvmcorepack 项目地址:https://github.com/nodejs/corepack#readme 场景 前端多项目依赖不同的 nodejs 版本和不同的包管理器(npm、yarn、pnpm) 解决方案 1、依赖不同 nodejs 版本使用 nvm 来解决,项目中新增 .nvmrc 来指定版本号 2、针对不同包管理器的问题使用node自带的 corepack 来解决 # 使用指定版本 node nvm us...

Nov 5, 20251 min read1

hello1024

46 posts