개발 시스템(Ubuntu 21.10 데스크탑) 중 하나에서 실행 중인 사용자 정의 애플리케이션이 오류와 함께 충돌합니다 socket: Too many open files
. 그래서 즉시 한도를 확인해 봤습니다. 출력은 다음과 같습니다.
$ ulimit -n
65535
이것이 이상한 이유는 애플리케이션이 충돌했을 때 1019 소켓만 사용했기 때문입니다. 아마도 다른 파일 설명자가 열려 있는 것을 고려하면 1024 제한에 도달한 것 같습니다.
데스크탑에 ulimit -n
한계가 65535라고 명확하게 명시되어 있지만 1024의 한계를 부과하는 이유는 무엇입니까?
더 이상하게 만들기 위해서입니다. 두 가지 응용 프로그램이 있습니다. 하나는 epoll
웹 스크레이퍼를 기반으로 하고 다른 하나는 연결을 시작하기 위해 여러 웹 서버에 메시지를 보내는 PACKET_MMAP
애플리케이션을 기반으로 합니다 . SYN
애플리케이션은 epoll
충돌하지 않지만 1024보다 훨씬 더 많은 소켓을 사용합니다. 그리고 PACKET_MMAP
원시 소켓을 사용하는 기본 애플리케이션이 충돌했습니다.
게다가 서버에서 테스트한 동일한 애플리케이션(또한 Ubuntu를 실행함)은 충돌하지 않습니다.
따라서 문제가 무엇이든 이는 데스크톱 및 원시 소켓 응용 프로그램에만 해당됩니다.
편집하다:
cat /proc/pid/limits
필요에 따라 출력:
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size 0 unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 31106 31106 processes
Max open files 1024 1048576 files
Max locked memory 1025802240 1025802240 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 31106 31106 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
출력은 최대 열린 파일에 대한 소프트 제한이 실제로 1024라는 것을 보여줍니다. 이는 ulimit -n
다음과 일치합니다.
답변1
사용자와 프로세스에 따라 리소스 제한을 다르게 설정할 수 있습니다. 특정 사용자에 대한 특정 제한을 표시 ulimit
하지만 systemd
고유한 기본 제한이 있습니다. systemd
파일 제한을 설정하려면 프로그램의 유닛 파일을 업데이트해야 합니다.LimitNOFILE=1048576
바라보다문서자세한 내용은
답변2
이것이 제가 C 코드로 이 문제를 해결한 방법입니다. 내 애플리케이션에 다음 코드 줄을 추가했습니다.
#include <sys/resource.h>
...
struct rlimit lim;
getrlimit(RLIMIT_NOFILE, &lim);
printf("Soft: %d Hard: %d\n", (int)lim.rlim_cur, (int)lim.rlim_max);
lim.rlim_cur = lim.rlim_max;
if (setrlimit(RLIMIT_NOFILE, &lim) == -1) {
printf("rlimit failed\n");
return -1;
}
getrlimit(RLIMIT_NOFILE, &lim);
printf("New Soft: %d New Hard: %d\n", (int)lim.rlim_cur, (int)lim.rlim_max);
하지만 아직 내 시스템의 구성 파일을 편집하여 이 작업을 수행하는 방법을 모르겠습니다. 그러나 이 답변은 C 코드 문제를 해결하는 데 만족하는 사람들에게 여전히 유용합니다.
답변3
Ubuntu Linux에서 systemd 관리 서비스의 제한을 변경하려면 override.conf 파일에서 이를 구성해야 합니다. 나는 예시로 mariadb를 사용하고 있지만 이는 모든 서비스에 일반화될 수 있습니다.
mkdir /etc/systemd/system/mariadb.service.d
vi /etc/systemd/system/mariadb.service.d/override.conf
이 파일에는 다음 줄을 입력합니다.
[Service]
LimitNOFILE=65535
그 후에는 단위 선언을 다시 로드해야 합니다.
systemctl daemon-reload
그리고 서비스를 다시 시작하세요
systemctl restart mariadb.service
이제 당신은 할 수 있습니다행정적 통제프로세스 제한. Systemd는 이 방법을 사용하여 다음 제한 사항을 관리할 수 있습니다.
지시하다 | ulimit 상당 | 단위 |
---|---|---|
CPU 제한= | ulimit -t | 초 |
제한FSIZE= | ulimit -f | 바이트 |
데이터 제한= | ulimit -d | 바이트 |
스택 제한 = | ulimit -s | 바이트 |
한계 코어 = | ulimit -c | 바이트 |
RSS 제한= | ulimit-m | 바이트 |
제한 NOFILE= | ulimit-n | 파일 설명자 수 |
제한 AS= | ulimit -v | 바이트 |
NPROC= 제한 | ulimit -u | 프로세스 수 |
한도MEMLOCK= | ulimit -l | 바이트 |
제한 잠금 = | ulimit-x | 잠금 수 |
서명 제한= | ulimit -i | 대기 중인 신호 수 |
제한 MSGQUEUE= | ulimit -q | 바이트 |
한도 NICE= | ulimit -e | 좋은 수준 |
제한 RTPRIO= | ulimit -r | 실시간 우선순위 |
제한RTTIME= | 상응하는 것이 없음 | 마이크로초 |
시스템 문서에서https://www.freedesktop.org/software/systemd/man/systemd.exec.html