Error socketpair creation failed too many open files

If my app runs for a longer period of time, I get the following error over and over again:

If my app runs for a longer period of time, I get the following error over and over again:

<Error>: tcp_connection_host_start 7181 DNSServiceGetAddrInfo failed: -65537
<Warning>: dnssd_clientstub deliver_request: socketpair failed 24 (Too many open files)

I have to completely kill the app and start it again. I didn’t find a way to reproduce this except for using the app for more than an hour.

I’m using Alamofire and MDWamp to make REST calls and send push messages.

Can somebody tell me what this error means exactly? Or ideas on how to reproduce it?

Kind regards,

Matthias

Accepted Reply

I FINALLY figured it out. MDWamp was using up File Descriptors like crazy because SSL Handshakes failed and I was reconnecting all the time.

This was really hard to reproduce because it takes a while until the maximum alllowed number of File Descriptors are used up and also when the build Scheme was set to Debug, the SSL Handshake did not fail… Well maybe somebody else would’ve guessed it in my position, but it certainly kept me busy for a while 🙂

For anybody who stumbles upon this and is interested, here is my GitHub issue for MDWamp documenting the problem and solution:

https://github.com/mogui/MDWamp/issues/42

Eskimo: Thank you so much for your help, without your descriptor counting code I wouldn’t know where I would be 😝 Also the release is planned in one week so I’m just really glad I finally figured it our!

Replies

Someone is leaking file descriptors within your process. You should run your app under load and periodically dump the file descriptor table to see if you can determine what type of file descriptor is leaking. Once you know that you can go hunting for the cause of the leak.

If the problem reproduces on the simulator you can dump the file descriptor table for your process using

lsof

. If you can only reproduce the problem on the device then things get a bit more complex. Post back in that case and I’ll explain the details.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I used this code to print my file descriptors:

Is that the right approach on the device?

That code is kinda broken. There are two specific issues:

  • FD_SETSIZE

    is not an appropriate substitute for

    getdtablesize

    .

  • F_GETPATH

    will only work for files; to test whether a descriptor is valid, you can use

    F_GETFL

    .

Here’s some code (copied from an old DevForums post) that does the right thing.

inUseDescCount = 0;
descCount = getdtablesize();
for (descIndex = 0; descIndex < descCount; descIndex++) {
    if ( fcntl(descIndex, F_GETFL) >= 0 ) {
        inUseDescCount += 1;
    }
}

So maybe my bug leads to a sudden increase in used file descriptors.

That’s certainly a possibility.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you for the code.

The ‘inUseDescCount’ does increase until about 2500 and then no calls are made anymore.

Sorry for my late response, we’re still trying to find out what is causing it. The whole bug only has a chance of appearing after the app ran a long time so this is rather annoying to reproduce.

Kind regards

Can you get it to happen on the simulator? If so, that offers of extra debugging tools (most notably, DTrace).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I FINALLY figured it out. MDWamp was using up File Descriptors like crazy because SSL Handshakes failed and I was reconnecting all the time.

This was really hard to reproduce because it takes a while until the maximum alllowed number of File Descriptors are used up and also when the build Scheme was set to Debug, the SSL Handshake did not fail… Well maybe somebody else would’ve guessed it in my position, but it certainly kept me busy for a while 🙂

For anybody who stumbles upon this and is interested, here is my GitHub issue for MDWamp documenting the problem and solution:

https://github.com/mogui/MDWamp/issues/42

Eskimo: Thank you so much for your help, without your descriptor counting code I wouldn’t know where I would be 😝 Also the release is planned in one week so I’m just really glad I finally figured it our!

Очень часто при работе на высоконагруженных Linux серверах могут возникать ошибки “too many open files”. Это означает, что процесс открыл слишком много файлов (читай файловых дескрипторов) и не может открыть новые. В Linux ограничения “max open file limit“ установлены по умолчанию для каждого процесса и пользователя, и они не слишком высокие.

В данной статье мы рассмотрим, как проверить текущие ограничения на количество открытых файлов в Linux, как изменить этот параметр для всего сервера, для отдельных сервисов и для сеанса. Статья применима для большинства современных дистрибутивов Linux (Debian, Ubuntu, CentOS, RHEL, Oracle Linux, Rocky и т.д.)

Содержание:

  • Ошибка: Too many open files и лимиты на количество открытых файлов в Linux
  • Глобальные ограничения на количество открытых файлов в Linux
  • Увеличить лимит открытых файловых дескрипторов для отдельного сервиса
  • Увеличить количество открытых файлов для Nginx и Apache
  • Лимиты file-max для текущей сессии

Ошибка: Too many open files и лимиты на количество открытых файлов в Linux

Чаще всего ошибку “too many open files“. Чаще всего эта ошибка встречается на серверах с установленным веб-сервером NGINX/httpd, сервером БД (MySQL/MariaDB/PostgreSQL), при чтении большого количества логов. Например, когда веб-серверу Nginx не хватает лимита для открытия файлов, вы получите ошибку:

socket () failed (24: Too many open files) while connecting to upstream

ошибка too many opne files в nginx

Или:

HTTP: Accept error: accept tcp [::]:<port_number>: accept4: too many open files.

В Python:

OSError: [Errno 24] Too many open files.

Максимально количество файловых дескрипторов, которые могут быть открыты в вашей файловой системе всеми процессами можно узнать так:

# cat /proc/sys/fs/file-max

Чтобы узнать, сколько файлов открыто сейчас, выполните:

$ cat /proc/sys/fs/file-nr

7744    521      92233720
  • 7744 — суммарное количество открытых файлов
  • 521– число открытых файлов, но которые сейчас не используются
  • 92233720– максимальное количество файлов, которое разрешено открывать

В Linux ограничение на максимальное количество открытых файлов можно натсроить на нескольких уровнях:

  • Ядра ОС
  • Сервиса
  • Пользователя

Чтобы вывести текущее ограничение на количество открытых файлов в ядре Linux, выполните:

# sysctl fs.file-max

fs.file-max = 92233720

fs.file-max - максимальное количество открытых файлов в linux

Выведем ограничение на количество открытых файлов для одного процесса текущего пользователя:

# ulimit -n

По умолчанию количество файлов для одного процесса этого ограничено числом 1024.

Выведем максимальное количество для одного пользователя (max user processes):

# ulimit –u

5041

Умножаем 1024 * 5041 дает нам 5161984 – это максимально количество открытых файлов всеми процессами пользователя.

В Linux есть два типа ограничений на количество открытых файлов: Hard и Soft. Soft ограничения носят рекомендательный характер, при превышении значения пользователь будет получать предупреждения. Если количество открытых файлов превысило hard лимит, пользователь не сможет открыть новые файлы пока не будет закрыты ранее открытые.

Для просмотра текущих лимитов используется команда ulimit с опцией
-S
(soft) или
-H
(hard) и параметром
-n
(the maximum number of open file descriptors).

Для вывода Soft-ограничения:

# ulimit -Sn

Для вывода Hard-ограничения:

# ulimit -Hn

ulimit hard квота на количество открытых дескрипторов

Глобальные ограничения на количество открытых файлов в Linux

Чтобы разрешить всем сервисам открывать большее количество файлов, можно изменить лимиты на уровне всей ОС Linux. Чтобы новые настройки работали постоянно и не сбрасывались при перезапуске сервера или сессии, нужно поправить файл /etc/security/limits.conf. Строки с разрешениями выглядит так:

Имя_пользователя тип_огрничение название_ограничения значение

Например:

apache  hard nofile 978160
apache soft nofile 978160

Вместо имени пользователя можно указать
*
. Это означает, что это ограничение будет применяться для всех пользователей Linux:

* hard nofile 97816
* soft nofile 97816

Например, вы получили ошибку too many open files для nginx. Проверьте, сколько файлов разрешено открывать процессу этому пользователю:

$ sudo -u nginx bash -c 'ulimit -n'

1024

Для нагруженного сервера этого недостаточно. Добавьте в /etc/security/limits.conf строки

nginx hard nofile 50000
nginx soft nofile 50000

В старых ядрах Linux значение fs.file-max может быть равно 10000. Поэтому проверьте это значение и увеличьте его, чтобы оно было больше чем ограничение в limits.conf:

# sysctl -w fs.file-max=500000

Это временно увеличит лимит. Чтобы новые настройки стали постоянными, нужно добавить в файл /etc/sysctl.conf строку:

fs.file-max = 500000

Проверьте, что в файле /etc/pam.d/common-session (Debian/Ubuntu или /etc/pam.d/login для CentOS/RedHat/Fedora) есть строчка:

session required pam_limits.so

Если нет, добавьте ее в конец. Она нужна, чтобы ограничения загружались при авторизации пользователя.

После изменений, перезапустите терминал и проверьте значение лимита max_open_files:

# ulimit -n

97816

Увеличить лимит открытых файловых дескрипторов для отдельного сервиса

Вы можете изменить лимит на количество открытых файловых дескрипторов для конкретного сервиса, а не для всей системы. Рассмотрим на примере apache. Чтобы изменить значения, откройте настройки службы через systemctl:

# systemctl edit httpd.service

Добавьте необходимые лимиты, например:

[Service]
LimitNOFILE=16000
LimitNOFILESoft=16000

nginx.conf настроить limitnofile

После изменения, нужно обновить конфигурацию сервиса и перезапустить его:

# systemctl daemon-reload
# systemctl restart httpd.service

Чтобы проверить, изменились ли значения, нужно получить PID сервиса:

# systemctl status httpd.service

Например, вы определил PID сервиса 32724:

# cat /proc/32724/limits | grep "Max open files”

Значение должно быть 16000.

настройка max open filex для сервиса в linux centos

Так вы изменили значения Max open files для конкретного сервиса.

Увеличить количество открытых файлов для Nginx и Apache

После того, как вы увеличил ограничения на количество открытых файлов для сервера, нужно также поправить конфигурационный файл службы. Например, для веб-сервера Nginx в файле конфигурации /etc/nginx/nginx.conf нужно задать значение в директиве:

worker_rlimit_nofile 16000

Директива worker_rlimit_nofile задает ограничение на количество файлов, открытых в рабочем процессе (
RLIMIT_NOFILE
). В Nginx файловые дескрипторы нужны для возврата статического файла из кэша для каждого подключения клиента. Чем больше пользователей использует ваш сервер и чем больше статических файлов отдает nginx, тем большее количество дескрипторов используется. Сверху максимальное количество дескрипторов ограничивается на уровне ОС и/или сервиса. При превышении количеств открытых файлов nginx появится ошибка
socket() failed (24: Too many open files) while connecting to upstream
.

При настройке Nginx на высоконагруженном 8-ядерном сервере с worker_connections 8192 нужно в worker_rlimit_nofile указать 8192*2*8 (vCPU) = 131072.

После чего выполнить рестарт Nginx:

# nginx -t && service nginx -s reload

Чтобы увидеть чисто открытых файлов для процессов пользователя nginx:

# su nginx
# ulimit –Hn
# for pid in `pidof nginx`; do echo "$(< /proc/$pid/cmdline)"; egrep 'files|Limit' /proc/$pid/limits; echo "Currently open files: $(ls -1 /proc/$pid/fd | wc -l)"; echo; done

Для apache, нужно создать директорию:

# mkdir /lib/systemd/system/httpd.service.d/

После этого создайте файл limit_nofile.conf:

# nano /lib/systemd/system/httpd.service.d/limit_nofile.conf

httpd изменить LimitNOFILE

И добавьте в него:

[Service]
LimitNOFILE=16000

Не забудьте перезапустить сервис httpd.

Лимиты file-max для текущей сессии

Чтобы изменить лимиты на открытые файлы в рамках текущей сессии пользователя, выполните команду:

# ulimit -n 3000

Если указать здесь значение большее, чем заданное в hard limit, появится ошибка:

-bash: ulimit: open files: cannot modify limit: Operation not permitted

задать ulimit max_files для пользователя в linux

Когда вы завершите текущую сессию терминала и откроете новую, лимиты вернутся к начальным значениям, указанным в файле /etc/security/limits.conf.

В данной статье мы разобрались, как решить проблему с недостаточным лимитом для открытых файловых дескрипторов в Linux и рассмотрели несколько вариантов изменения лимитов на сервере.

Если вы работали с программами, которым приходится обрабатывать очень большое количество файловых дескрипторов, например с распределенными базами данных, такими, как Elasticsearch, то вы, наверняка, сталкивались с ошибкой «too many open files в Linux».

В этой небольшой статье мы разберемся, что означает эта ошибка, а также как её исправить в различных ситуациях.

Дословно эта ошибка означает, что программа открыла слишком много файлов и больше ей открывать нельзя. В Linux установлены жёсткие ограничения на количество открываемых файлов для каждого процесса и пользователя.

Посмотреть, сколько файлов можно открыть в вашей файловой системе, можно, выполнив команду:

cat /proc/sys/fs/file-max

Посмотреть текущие ограничения количества открытых файлов для пользователя можно командой:

ulimit -n

Утилита ulimit возвращает два вида ограничений — hard и soft. Ограничение soft вы можете менять в любую сторону, пока оно не превышает hard. Ограничение hard можно менять только в меньшую сторону от имени обычного пользователя. От имени суперпользователя можно менять оба вида ограничений так, как нужно. По умолчанию отображаются soft-ограничения:

ulimit -nS

Чтобы вывести hard, используйте опцию -H:

ulimit -nH

Вы можете изменить ограничение, просто передав в ulimit новое значение:

ulimit -n 3000

Но поскольку hard-ограничение составляет 4000, то установить лимит больше этого значения вы не сможете. Чтобы изменить настройки ограничений для пользователя на постоянной основе, нужно настроить файл /etc/security/limits.conf. Синтаксис у него такой:

имя_пользователя тип_ограничения название_ограничения значение

Вместо имени пользователя можно использовать звездочку, чтобы изменения применялись ко всем пользователям в системе. Тип ограничения может быть soft или hard. Название — в нашем случае нужно nofile. И последний пункт — нужное значение. Установим максимум — 1617596.

sudo vi /etc/security/limits.conf

* hard nofile 1617596
* soft nofile 1617596

Нужно установить значение для soft и hard параметра, если вы хотите, чтобы изменения вступили в силу. Также убедитесь, что в файле /etc/pam.d/common-session есть такая строчка:

session required pam_limits.so

Если её нет, добавьте в конец. Она нужна, чтобы ваши ограничения загружались при авторизации пользователя.

Если вам нужно настроить ограничения только для определенного сервиса, например  Apache или Elasticsearch, то для этого не обязательно менять все настройки в системе. Вы можете сделать это с помощью systemctl. Просто выполните:

sudo systemctl edit имя_сервиса

И добавьте в открывшейся файл такие строки:

[Service]
LimitNOFILE=1617596
LimitNOFILESoft=1617596

Здесь мы устанавливаем максимально возможное ограничение как для hard- так и для soft-параметра. Дальше нужно закрыть этот файл и обновить конфигурацию сервисов:

sudo systemctl daemon-reload

Затем перезагрузить нужный сервис:

sudo systemctl restart имя_сервиса

Убедится, что для вашего сервиса применились нужные ограничения, можно, открыв файл по пути /proc/pid_сервиса/limits. Сначала смотрим PID нужного нам сервиса:

ps aux | grep elasticsearch

Затем смотрим информацию:

cat /proc/8388/limits

Выводы

В этой небольшой статье мы разобрали, что делать, если возникает ошибка «слишком много открытых файлов Linux», а также как изменять ограничения на количество открытых файлов для пользователя и процесса в Linux.

Creative Commons License

Статья распространяется под лицензией Creative Commons ShareAlike 4.0 при копировании материала ссылка на источник обязательна .

Об авторе

Основатель и администратор сайта losst.ru, увлекаюсь открытым программным обеспечением и операционной системой Linux. В качестве основной ОС сейчас использую Ubuntu. Кроме Linux, интересуюсь всем, что связано с информационными технологиями и современной наукой.

Linux users often come across the error, ‘Too Many Open Files’ due to high load in the server, leaving it hard for us to open multiple files.

We, at Bobcares have experienced similar error and our Server Administration Team have come up with effective solutions.

Today, let’s check how to find the limit of maximum number of open files set by Linux and how we alter it for an entire host, individual service or a current session.

Where can we find error, ‘Too Many Open Files’?

Since Linux has set a maximum open file limit by default, the system has a method for restricting the number of various resources a process can consume.

Usually the ‘Too Many Open Files’ error is found on servers with an installed NGINX/httpd web server or a database server (MySQL/MariaDB/PostgreSQL).

Too Many Opem Files

For example, when an Nginx web server exceeds the open file limit, we come across an error:

socket () failed (29: Too many open files) while connecting to upstream

To find the maximum number of file descriptors a system can open, run the following command:

# cat /proc/sys/fs/file-max

The open file limit for a current user is 1024. We can check it as follows:

# ulimit -n [root@server /]# cat /proc/sys/fs/file-max 97816 [root@server /]# ulimit -n 1024

There are two limit types: Hard and Soft. Any user can change a soft limit value but only a privileged or root user can modify a hard limit value.

However, the soft limit value cannot exceed the hard limit value.

To display the soft limit value, run the command:

To display the hard limit value:

‘Too Many Open Files’ error & Open File Limits in Linux

Now we know that these titles mean that a process has opened too many files (file descriptors) and cannot open new ones. In Linux, the maximum open file limits are set by default for each process or user and the values are rather small.

We, at Bobcares have monitored this closely and have come up with a few solutions:

Increase the Max Open File Limit in Linux

A large number of files can be opened if we change the limits in our Linux OS. In order to make new settings permanent and prevent their reset after a server or session restart, make changes to /etc/security/limits.conf. by adding these lines:

  • hard nofile 97816
  • soft nofile 97816

If it is using Ubuntu, add this line as well:

session required pam_limits.so

These parameters allow to set open file limits after user authentication.

After making the changes, reload the terminal and check the max_open_files value:

Increase the Open File Descriptor Limit per service

A change in the limit of open file descriptors for a specific service, rather than for an entire operating system is possible.

For example, if we take Apache, to change the limits, open the service settings using systemctl:

systemctl edit httpd.service

Once the service settings is open, add the limits required. For example;

[Service] LimitNOFILE=16000 LimitNOFILESoft=16000

After making the changes, update the service configuration and restart it:

# systemctl daemon-reload # systemctl restart httpd.service

To ensure the values have changed, get the service PID:

# systemctl status httpd.service

For example, if the service PID is 3724:

# cat /proc/3724/limits | grep “Max open files”

Thus, we can change the values for the maximum number of open files for a specific service.

Set Max Open Files Limit for Nginx & Apache

In addition to changing the limit on the number of open files to a web server, we should change the service configuration file.

For example, specify/change the following directive value in the Nginx configuration file /etc/nginx/nginx.conf:

worker_rlimit_nofile 16000

While configuring Nginx on a highly loaded 8-core server with worker_connections 8192, we need to specify

8192*2*8 (vCPU) = 131072 in worker_rlimit_nofile

Then restart Nginx.

For apache, create a directory:

# mkdir /lib/systemd/system/httpd.service.d/

Then create the limit_nofile.conf file:

# nano /lib/systemd/system/httpd.service.d/limit_nofile.conf

Add to it:

[Service] LimitNOFILE=16000

Do not forget to restart httpd.

Alter the Open File Limit for Current Session

To begin with, run the command:

Once the terminal is closed and a new session is created, the limits will get back to the original values specified in /etc/security/limits.conf.

To change the general value for the system /proc/sys/fs/file-max, change the fs.file-max value in /etc/sysctl.conf:

Finally, apply:

# sysctl -p [root@server /]# sysctl -p net.ipv4.ip_forward = 1 fs.file-max = 200000 [root@server /]# cat /proc/sys/fs/file-max 200000

[Despite all the above solutions if the issue still prevail, don’t panic. We have our Experienced Tech Team working round the clock to help you fix it for you.]

Conclusion

To conclude, today, we figured how our Support Engineers solve the error, ‘Too Many Open Files’ and discussed options to change the default limits set by Linux.

We saw that the default value of open file descriptor limit in Linux is too small, and discussed a few options for changing these limits of the server.

PREVENT YOUR SERVER FROM CRASHING!

Never again lose customers to poor server speed! Let us help you.

Our server experts will monitor & maintain your server 24/7 so that it remains lightning fast and secure.

GET STARTED

var google_conversion_label = «owonCMyG5nEQ0aD71QM»;

Понравилась статья? Поделить с друзьями:
  • Error socket does not name a type
  • Error soc init t17 antminer
  • Error soc init s19
  • Error soc init s17
  • Error snowshoe 593036c0