В чем причина Broken Pipe на сокетах домена Unix?

У меня есть серверное приложение, которое получает запросы и пересылает их в сокет домена Unix. Это прекрасно работает при разумном использовании, но когда я выполняю нагрузочные тесты с несколькими тысячами запросов, я получаю ошибку Broken Pipe.

Я использую Java 7 с junixsocket для отправки запросов. У меня есть много одновременных запросов, но у меня есть пул потоков из 20 рабочих, которые пишут в сокет домена unix, поэтому нет проблемы слишком большого количества одновременных открытых подключений.

Для каждого запроса я открываю, отправляю и закрываю соединение с сокетом домена Unix.

Какова причина, которая может привести к поломке канала на сокетах домена Unix?

ОБНОВЛЕНИЕ:

Пример кода, если требуется:

byte[] mydata = new byte[1024];
//fill the data with bytes ...

AFUNIXSocketAddress socketAddress = new AFUNIXSocketAddress(new File("/tmp/my.sock"));
Socket socket = AFUNIXSocket.connectTo(socketAddress);
OutputStream out = new BufferedOutputStream(socket.getOutputStream());
InputStream in = new BufferedInputStream(socket.getInputStream()));

out.write(mydata);
out.flush();  //The Broken Pipe occurs here, but only after a few thousand times

//read the response back...

out.close();
in.close();
socket.close();

У меня есть пул потоков из 20 рабочих, и они делают все вышеперечисленное одновременно (таким образом, до 20 одновременных подключений к одному и тому же сокету домена Unix), каждый из которых открывает, отправляет и закрывает. Это отлично работает для нагрузочного теста из 10 000 запросов, но когда я добавляю еще несколько тысяч, я внезапно получаю эту ошибку, поэтому мне интересно, происходит ли это из-за какого-то предела ОС.

Имейте в виду, что это сокет домена Unix, а не сетевой сокет TCP.


person jbx    schedule 15.04.2012    source источник
comment
см. (Что вызывает ошибку сломанной трубы) [stackoverflow.com/questions/4584904/   -  person Shehzad    schedule 15.04.2012
comment
@jbx Я также наблюдаю такое поведение у клиента AFUNIXSocket. Вы когда-нибудь находили основную причину?   -  person tjdett    schedule 16.10.2015
comment
@tjdett Это слишком долго, чтобы я мог вспомнить. Однако я думаю, что увеличил ограничения файлов, такие как количество открытых файлов и открытых сокетов.   -  person jbx    schedule 16.10.2015


Ответы (1)


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

person user207421    schedule 15.04.2012
comment
Спасибо, но это сокет домена Unix, а не обычный сокет TCP, где сломанный канал обычно вызывается проблемами с сетью или сервером, закрывающим соединение некрасивым образом. - person jbx; 20.04.2012
comment
@jbx Все это неправда. «Сломанный канал» всегда означает, что одноранговый узел закрыл соединение, и ничего больше, будь то TCP или домен Unix. Сетевые ошибки не вызывают эту проблему. Эту проблему вызовут как изящные, так и неблагодарные закрытия. - person user207421; 20.04.2012
comment
Да, но почему это происходит в сокете домена Unix? По сути, это локальный дескриптор файла в ОС. Нет другой стороны, которая что-то закрывает, это все локально. - person jbx; 20.04.2012
comment
@jbx Потому что одноранговый узел закрыл соединение. В этом случае одноранговый узел — это другой процесс в той же ОС, но он все еще является одноранговым. - person user207421; 20.04.2012
comment
Хорошо, а почему процесс закрывает соединение? Почему это работает для первых 10 000 запросов, а потом это происходит на ровном месте? (10 000 — это не точное число, на самом деле его больше, но оно не достигает предела в 20 000 нагрузочных тестов) - person jbx; 20.04.2012
comment
@jbx Я не знаю. Это ваш процесс, не мой. Но он закрывается. Вот что значит исключение. - person user207421; 20.04.2012
comment
Нет, он не закрывается, вот и все, что я пытаюсь понять. Процесс прослушивания - это не мой процесс, это php fcgi, и его не нужно закрывать. Это вызывает какое-то условие загрузки, но в журналах ничего нет, поэтому и возникает вопрос. - person jbx; 20.04.2012
comment
@jbx Как говорят в АА, первый шаг — выйти из режима отрицания. Вы получаете ошибку «сломанная труба». Это происходит, когда одноранговый узел закрывает свой сокет, и ни при каких других обстоятельствах. Следовательно, узел закрывает свой сокет. Период. Пунто баста. Финис. Энде. Почему, это другой вопрос. - person user207421; 20.04.2012
comment
Лол режим отрицания. В ПОРЯДКЕ. Может быть... просто может быть... что мой нагрузочный тест заполняет какой-то буфер ОС, поэтому я получаю сообщение об ошибке именно тогда, когда пытаюсь сбросить () данные? Я просто пытаюсь найти взаимосвязь между моим тестом и поведением. - person jbx; 20.04.2012
comment
@jbx Именно тогда я ожидал, что ты это получишь. Буфер ОС есть, и он может заполниться нормально: это заблокирует вашу запись или сброс, а не вызовет эту ошибку. Причина остается той, о которой я говорил выше, несколько раз. - person user207421; 20.04.2012
comment
Отключение на другом конце — не единственная возможная причина поломки пайпа на доменном сокете. Я пытаюсь решить эту проблему для программы на С++, над которой я работаю. Со стороны чтения доменного сокета все в порядке, но сторона записи создает SIGPIPE. Я отследил выполнение обоих процессов, и ни один из них никогда не закрывает сокет. - person Brian Vandenberg; 11.06.2020