connect: resource temporarily unavailable (что значает ошибка и как с ней бороться?)

Модератор: Модераторы разделов

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 18294
Статус: grammatikführer
ОС: Debian GNU/Linux

connect: resource temporarily unavailable

Сообщение Bizdelnick »

Имеется написанная на go софтина, которая подключается к доменному сокету, который слушает написанная на C++ софтина. Периодически при высокой нагрузке появляются такие ошибки:

Код: Выделить всё

dial unix <путь к сокету>: connect: resource temporarily unavailable
В мане connect(2) написано по этому поводу совсем немного:
EAGAIN Insufficient entries in the routing cache.
Какой ещё кеш имеется в виду? И в нём ли дело? Что можно подкрутить в системе (коя linux, если это важно)?
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 18294
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: connect: resource temporarily unavailable

Сообщение Bizdelnick »

А вот как это выглядит в strace:

Код: Выделить всё

23664 socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 1167
23664 connect(1167, {sa_family=AF_UNIX, sun_path="<путь к сокету>"}, 16) = -1 EAGAIN (Ресурс временно недоступен)
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
/dev/random
Администратор
Сообщения: 5098
ОС: Gentoo

Re: connect: resource temporarily unavailable

Сообщение /dev/random »

Bizdelnick писал:
03.12.2020 16:54
В мане connect(2) написано по этому поводу совсем немного:
EAGAIN Insufficient entries in the routing cache.
У меня написано по-другому (Linux man-pages 5.08):
EAGAIN For nonblocking UNIX domain sockets, the socket is nonblocking, and the connection cannot be completed immediately. For other socket families, there are insufficient entries in the routing cache.
И судя по логу strace, здесь именно неблокирующий unix-сокет.
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 18294
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: connect: resource temporarily unavailable

Сообщение Bizdelnick »

/dev/random писал:
04.12.2020 03:40
the socket is nonblocking, and the connection cannot be completed immediately
Это выглядит более разумно, но всё-таки не проясняет причину ошибки. Можно ли что-то с этим сделать на стороне клиента, сервера или ОС? (Ну кроме очевидного «использовать блокирующие сокеты»: я не готов переписывать половину стандартной библиотеки go, да и вряд ли это вообще возможно.)
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
/dev/random
Администратор
Сообщения: 5098
ОС: Gentoo

Re: connect: resource temporarily unavailable

Сообщение /dev/random »

Bizdelnick писал:
04.12.2020 16:48
Это выглядит более разумно, но всё-таки не проясняет причину ошибки. Можно ли что-то с этим сделать на стороне клиента, сервера или ОС? (Ну кроме очевидного «использовать блокирующие сокеты»: я не готов переписывать половину стандартной библиотеки go, да и вряд ли это вообще возможно.)
Обычно это происходит, если очередь установленных через connect(), но не принятых через accept() соединений заполнена. Размер очереди указывается в listen(). Максимальный размер, до которого обрезается указанный в listen() параметр - в sysctl net.core.somaxconn. Если нет возможности повлиять на то, как Go реагирует на EAGAIN, можно попробовать увеличить эту очередь.
Спасибо сказали:

Аватара пользователя
Dionysius
Сообщения: 443
ОС: Manjaro

Re: connect: resource temporarily unavailable

Сообщение Dionysius »

Bizdelnick писал:
04.12.2020 16:48
/dev/random писал:
04.12.2020 03:40
the socket is nonblocking, and the connection cannot be completed immediately
Это выглядит более разумно, но всё-таки не проясняет причину ошибки. Можно ли что-то с этим сделать на стороне клиента, сервера или ОС? (Ну кроме очевидного «использовать блокирующие сокеты»: я не готов переписывать половину стандартной библиотеки go, да и вряд ли это вообще возможно.)
В этой статье объясняют причину так:
Instead of blocking, a call to read() on an empty pipe or write() to a full pipe will return an EAGAIN error. This is a nice way of saying the pipe is not ready for that action (the error message might look like resource temporarily unavailable). EAGAIN really means “try again”, there is an alias for this error called EWOULDBLOCK.
и советуют использовать поллинг, чтобы
to be notified of when the pipe is ready for read or write (depending on what you need).
Последний раз редактировалось Dionysius 04.12.2020 19:04, всего редактировалось 1 раз.
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 18294
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: connect: resource temporarily unavailable

Сообщение Bizdelnick »

/dev/random писал:
04.12.2020 18:13
Обычно это происходит, если очередь установленных через connect(), но не принятых через accept() соединений заполнена. Размер очереди указывается в listen(). Максимальный размер, до которого обрезается указанный в listen() параметр - в sysctl net.core.somaxconn. Если нет возможности повлиять на то, как Go реагирует на EAGAIN, можно попробовать увеличить эту очередь.
О, спасибо! Придётся, правда, покопаться, чтобы найти, где это зарыто в asio, но хотя бы направление понятно.
Добавлено (18:47):
Dionysius, спасибо, но к сокетам это не очень применимо.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 18294
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: connect: resource temporarily unavailable

Сообщение Bizdelnick »

Как выяснилось, размер очереди задан 128, что соответствует умолчальному лимиту в моей системе. Не уверен, есть ли смысл его увеличивать, но сходу одолеть asio в любом случае не вышло. Пока решил проблему, добавив попытки повторного подключения со стороны клиента.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали: