【问题标题】:What is the reason for Broken Pipe on Unix Domain Sockets?Unix域套接字上的Broken Pipe的原因是什么?
【发布时间】:2012-04-15 16:17:12
【问题描述】:

我有一个服务器应用程序,它接收请求并在 Unix 域套接字上转发它们。这在合理使用下完美运行,但是当我对几千个请求进行一些负载测试时,我收到了 Broken Pipe 错误。

我正在使用带有junixsocket 的Java 7 来发送请求。我有很多并发请求,但是我有一个包含 20 个工作线程的线程池正在写入 unix 域套接字,因此不存在并发打开连接过多的问题。

对于我打开、发送和关闭与 Unix 域套接字的连接的每个请求。

在 Unix Domain Sockets 上可能导致 Broken Pipe 的原因是什么?

更新:

如果需要,放一个代码示例:

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 套接字。

【问题讨论】:

  • 查看(导致断管错误的原因)[stackoverflow.com/questions/4584904/…
  • @jbx 我也从AFUNIXSocket 客户端看到了这种行为。你找到根本原因了吗?
  • @tjdett 它有点太长了,我记不住。但是,我认为我增加了文件限制,例如打开文件和打开套接字的数量。

标签: java unix broken-pipe unix-socket


【解决方案1】:

'Broken pipe' 表示您已写入已被另一端关闭的连接。由于缓冲,它的检测有些异步。这基本上意味着您的应用程序协议中有错误。

【讨论】:

  • 谢谢,但这是一个 Unix 域套接字,它不是一个正常的 TCP 套接字,其中一个损坏的管道通常是由网络问题或服务器以非正常方式关闭连接引起的。
  • @jbx 这些都不是真的。 'Broken pipe' 总是意味着对等方关闭了连接,没有别的,无论是 TCP 还是 Unix 域。网络错误不会导致此问题。优雅关闭和忘恩负义的关闭都会导致这个问题。
  • 是的,但为什么会发生在 Unix 域套接字上?它本质上是操作系统上的本地文件句柄。没有其他方面正在关闭所有本地的东西。
  • @jbx 因为对端关闭了连接。在这种情况下,对等点是同一操作系统中的另一个进程,但它仍然是对等点。
  • @jbx 正如他们在 AA 所说,第一步是退出拒绝模式。您收到“管道破损”错误。当对等方关闭其套接字时会发生这种情况,在任何其他情况下都不会发生。因此,对等方正在关闭其套接字。时期。蓬托巴斯塔。菲尼斯。恩德。为什么,是另一个问题。
【解决方案2】:

来自Linux Programmer's Manual(Mac 上的套接字手册页中也有类似的语言):

实现 SOCK_STREAM 的通信协议确保数据不会丢失或重复。如果对等协议有缓冲空间的一段数据在合理的时间内不能成功传输,则认为该连接已死。当在套接字上启用 SO_KEEPALIVE 时,协议以特定于协议的方式检查另一端是否还活着。如果进程在中断的流上发送或接收,则会引发 SIGPIPE 信号;这会导致不处理信号的幼稚进程退出。

换句话说,如果数据在流套接字中停留的时间过长,您最终会得到一个 SIGPIPE。如果您无法跟上负载测试,那么您最终会遇到这种情况是合理的。

【讨论】:

  • 这是一篇很老的帖子,但仍然......如果你读了我的问题,我清楚地说它不是 TCP 套接字,它是 UNIX 域套接字,所以完全是本地进程间通信。跨度>
  • @jbx 抱歉,我意识到我的术语是错误的。 UDP/数据报甚至不应该成为这个对话的一部分,我应该说“流套接字”而不是 TCP。我一直倾向于使用后者,因为一旦你插入它们的地址,UNIX 流套接字就像 TCP 套接字一样出现在你的程序中,因为你使用相同的系统调用并在它们上动态监听/连接,并且你可以运行 TCP 协议,例如HTTP 在他们身上。不过,我的大部分答案仍然有效,因为它取自未提及 TCP 的文档 - 错误完全是我的。
  • 就我而言,没有数据被卡住。我想如果我记得很清楚(自从 9 年过去了),问题是我达到了系统的默认最大连接和文件限制。我增加了 fs.file-maxnet.core.somaxconn 之类的东西,问题就消失了。
猜你喜欢
  • 1970-01-01
  • 2021-05-26
  • 1970-01-01
  • 1970-01-01
  • 2016-03-30
  • 2010-12-06
  • 1970-01-01
  • 1970-01-01
  • 2010-11-13
相关资源
最近更新 更多