You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Red Hat 9下systemd服务调用POSIX消息队列报错求助

RHEL9下systemd守护进程调用POSIX消息队列报"Too many open files"错误的解决

在Red Hat 9系统中搭建调用POSIX消息队列的systemd守护进程服务时,启动阶段出现mq_open: Too many open files(错误码24)问题。已尝试多种系统配置调整但无效,且因需求限制无法修改二进制代码,现提供无需修改程序的外部配置解决方案。


相关代码与配置

二进制源码

#include <iostream>
#include <sys/stat.h>
#include <fcntl.h>
#include <mqueue.h>
#include <cstdio>
#include <sys/resource.h> /* RLIM_INFINITY*/
using namespace std;

typedef struct mq_attr mq_attr_t;

int main() {
    /* Create and open a message queue for writing */
    mqd_t mqd = mq_open ("/OpenCSF_MQ", O_CREAT | O_EXCL | O_WRONLY,  0600, NULL);
    
    /* Ensure the creation was successful */
    if (mqd == -1)
      {
        perror ("mq_open");
        exit (1);
      }
    
    /* Send "HELLO" as a message with priority 10, then close the queue.
       Note the size is 6 to include the null byte '\0'. */
    mq_send (mqd, "HELLO", 6, 10);
    mq_close (mqd);
}

编译命令

g++ -lrt -o simplemq

systemd服务文件

[Unit]
Description= service for test mq
After=network.target
DefaultDependencies=no
Before=sysinit.target
ConditionPathExists=/proc/sys/fs/mqueue
ConditionCapability=CAP_SYS_ADMIN
MessageQueueMaxMessages=3072
MessageQueueMessageSize=3000

[Service]
# Type=forking
 Type=exec
 User=root
 Group=root
 ExecStart=simplemq
 TimeoutStartSec=0
 LimitNOFILE=5000000
 LimitMSGQUEUE=4000
 CapabilityBoundingSet=CAP_SYS_RESOURCE
[Install]
WantedBy=default.target

错误日志

Nov 24 13:03:30 test-server-rhel9 systemd[1]: Starting service for test mq...
Nov 24 13:03:30 test-server-rhel9 systemd[1]: Started service for test mq.
Nov 24 13:03:30 test-server-rhel9 simplemq[2956]: mq_open: Too many open files
Nov 24 13:03:30 test-server-rhel9 systemd[1]: test.service: Main process exited, code=exited, status=1/FAILURE
Nov 24 13:03:30 test-server-rhel9 systemd[1]: test.service: Failed with result 'exit-code'.

已尝试的无效配置

  • 修改/etc/systemd/system.conf和user.conf,设置DefaultLimitNOFILE=499999、DefaultLimitMSGQUEUE=500000
  • 调整/proc/sys/fs/mqueue参数:msg_default=10、msg_max=3072、msgsize_default=8192、msgsize_max=8192、queues_max=256
  • 配置/etc/security/limits.conf:* hard/soft msgqueue unlimited、root hard/soft nofile unlimited
  • 修改/etc/sysctl.conf:fs.mqueue.msg_max=3072、fs.mqueue.queue_max=350

解决方案

1. 修正systemd服务文件的RLIMIT_MSGQUEUE配置

systemd中LimitMSGQUEUE的单位是字节而非消息数,原配置的4000字节不足以创建消息队列。直接设置为无限或足够大的字节值:
修改服务文件的[Service]段:

[Service]
Type=exec
User=root
Group=root
ExecStart=simplemq
TimeoutStartSec=0
LimitNOFILE=5000000
LimitMSGQUEUE=infinity
CapabilityBoundingSet=CAP_SYS_RESOURCE

2. 确保systemd配置生效

修改服务文件后,重新加载systemd配置并重启服务:

systemctl daemon-reload
systemctl restart test.service

3. 验证服务资源限制

检查服务的实际资源限制是否生效:

systemctl show test.service | grep LimitMsgQueue

若返回值不符合预期,需确认systemd版本兼容性,或在服务文件中强制设置更高优先级的限制。

4. 清理残留消息队列

残留的消息队列可能占用资源,导致创建失败,执行以下命令清理:

ls /dev/mqueue/
rm /dev/mqueue/OpenCSF_MQ

5. 调整系统默认消息队列参数

若程序创建队列时未指定属性,会使用系统默认值,可适当调大:
临时生效:

echo 100 > /proc/sys/fs/mqueue/msg_default
echo 8192 > /proc/sys/fs/mqueue/msgsize_default

永久生效(添加到/etc/sysctl.conf):

fs.mqueue.msg_default=100
fs.mqueue.msgsize_default=8192

执行sysctl -p使配置生效。


内容的提问来源于stack exchange,提问作者Apollo17

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 10:17:29