지난 6개월 동안 나는 제거할 수 없는 문제에 직면해 있었습니다. 무작위로 "열린 파일이 너무 많습니다"/"TCP/IP 소켓을 열 수 없습니다(24)"/"getaddrinfo: OK" I 내 응용 프로그램 로그에 "파일을 열지 않음" 오류가 표시됩니다.
나는 다음과 같은 스택을 실행합니다: mariadb, postgresql, memcached, redis 및 Docker 컨테이너 내의 여러 노드 기반 애플리케이션, Ruby on Rails(ruby 2.5.5, Rails 6) 애플리케이션 및 sidekiq를 실행하는 Passenger가 있는 Apache, 모두 CentOS 7 시스템에서 (3.10.0-1127.el7.x86_64), 6개 코어 및 16GB RAM. 부하는 평균 약 10%이며 주 근무 시간 동안에는 작은 피크가 나타나고 30%를 초과하는 경우는 거의 없습니다.
처음에는 다른 Java 응용 프로그램이 문제를 일으키는 것으로 생각했고 응용 프로그램을 닫은 후에도 얼마 후에 문제가 계속 발생했습니다.
내가 무엇을 하든 이를 CLI에서 재현할 수 없습니다. 이는 분명히 시스템에 큰 부하 없이 무작위로 발생하는 것 같습니다.
서비스가 다시 시작된 지 1시간 후에 다음과 같은 통계가 표시됩니다.
열린 파일의 총 개수
$ lsof | wc -l
30594
열린 파일별 상위 프로세스
$ lsof | awk '{print $1}' | sort | uniq -c | sort -r -n | head
8260 mysqld
4804 node
2728 Passenger
2491 container
2095 postgres
1445 dockerd
1320 processor
817 php-fpm
720 httpd
709 ruby
MariaDB 변수:
MariaDB [(none)]> Show global variables like 'open_files_limit';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| open_files_limit | 65535 |
+------------------+-------+
1 row in set (0.01 sec)
MariaDB [(none)]> Show global status like 'opened_files';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Opened_files | 6151 |
+---------------+-------+
1 row in set (0.00 sec)
sysctl.conf의 최대 오픈 파일 수를 130k로 설정하면 문제가 해결될 것이라고 생각하고 시간을 좀 벌었지만 나중에 계속 나타납니다.
$ sysctl fs.file-nr
fs.file-nr = 3360 0 131070
방금 빠른 "ab" 테스트를 수행했는데 열린 파일 수가 너무 많이 증가하지 않았습니다.
$ ab -n 1000 -c 10 http://www.example.com/
9589 mysqld
4804 node
4577 Passenger
3756 httpd
3225 postgres
2491 container
2166 utils.rb:
2080 ruby
1445 dockerd
1364 processor
실제 사용자는 홈페이지를 반복적으로 방문하지 않으므로 이는 중요하지 않을 수 있습니다.
범인이 Docker일 수도 있다는 예감이 들지만(데이터베이스를 Docker화하지 않고 더 바쁜 서버를 실행했습니다) 데이터베이스를 Docker에서 이동하기 전에 다른 가능성을 조사하는 것이 매우 고통스러운 프로세스가 될 것이기 때문에 조사하고 싶습니다.
몇 가지 조언을 얻을 수 있기를 바랍니다.
답변1
이는 4096개의 inotify 핸들러만 있기 때문입니다. 한도를 늘렸더니 문제가 사라졌습니다.
fs.file-max = 131070
fs.inotify.max_user_watches = 65536