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
相关产品推荐
相关产品推荐

