参数是什么
kernel.msgmax 是 Linux 内核 SysV 消息队列(CONFIG_SYSVIPC)允许的单条消息字节上限,常见默认值 8192。应用调用 msgsnd() 投递时,内核先校验消息长度(含前导的类型字段)是否超过该值,超限直接返回 EINVAL,不会进入排队等待。它与另外两个参数共同构成限额:msgmax 管单条消息,msgmnb 管单个队列的累计字节(常见默认 16384),msgmni 管系统内队列总数(默认值随内核版本与内存变化)。
基本信息
| 适用平台 | Linux(CentOS/RHEL、Ubuntu/Debian、SUSE) |
|---|---|
| 相关接口 | msgget / msgsnd / msgrcv / ipcs |
| 单位 | 字节 |
| 常见默认值 | msgmax 8192、msgmnb 16384 |
| 权限要求 | 查看无需特权,修改需 root 或 CAP_SYS_ADMIN |
| 持久化 | 写入 /etc/sysctl.d/*.conf 后执行 sysctl --system |
典型使用场景
- 安装传统企业应用(银行核心、ERP、老版中间件)时,厂商基线文档要求同时调大 msgmax/msgmnb/msgmni
- 应用日志出现 msgsnd: Invalid argument 或返回 EINVAL,需确认消息体是否超过单条上限
- 批处理一次投递整条结构化报文(单条几十 KB),需要提高 msgmax 并同步放宽 msgmnb
- 排查消息队列积压:结合 ipcs -q 的 used-bytes 与 Messages 列判断是消费慢还是单条放不下
- 容器与宿主共享 IPC 命名空间时,限额由宿主内核参数决定,容器内看到的也是宿主值
查看与调整
查看与调整
ipcs -l # 打印消息队列、共享内存、信号量三类的当前限额
ipcs -q # 只列现有消息队列,关注 used-bytes 与 Messages 两列
sysctl kernel.msgmax kernel.msgmnb kernel.msgmni # 查看当前内核参数值
sysctl -w kernel.msgmax=65536 # 临时调整,重启后回退
printf 'kernel.msgmax = 65536\nkernel.msgmnb = 1048576\n' > /etc/sysctl.d/90-ipc.conf # 持久化
sysctl --system # 重新加载全部配置并回显,确认写入生效报错对照
| 错误码 | 含义 | 排查动作 |
|---|---|---|
| EINVAL | 单条消息超过 msgmax,或消息结构非法 | 核对消息长度是否超过 msgmax,必要时同步抬高 msgmnb |
| EAGAIN | 队列已满(msgmnb 到顶)且使用了非阻塞发送 | 看 ipcs -q 的 used-bytes 与消费者速度,别只调单条上限 |
| ENOMEM | 内核内存不足,无法再为队列分配空间 | 查系统整体内存与 slab 占用,而不是继续抬参数 |
单条消息长度还受 msgmnb 约束:如果 msgmax 大于等于 msgmnb,单条消息永远无法完整入队。抬 msgmax 时应同时抬 msgmnb,并按「并发消息条数 × 单条大小」估算队列容量。
现代应用大多改用 POSIX 消息队列(mq_send)或 Kafka/RabbitMQ 一类中间件,它们不受这三个参数约束。排障前先确认应用用的是 SysV IPC 还是 POSIX 接口,避免调了参数却毫无效果。