socketchannel.write() becomes very slow when message size is large

孤街浪徒 提交于 2019-12-04 19:25:17

If write takes more than 20 micro-seconds, I would suggest you have a buffer full issue. I assume you are using blocking NIO. When the send buffer is not full it usually takes between 5 - 20 micro-seconds. In the past I have configured my server to kill any slow consumer which takes 2 ms to write. (Possibly a bit aggressive. ;)

You could try increasing the size of the send buffer (Socket.setSendBufferSize(int), which is also available for SocketChannels), but it would appear you are trying to send more data than your bandwidth allows.

10 KB is not a large message, the typical send buffer size is 64 KB, so for it to be full you would need to have 6-7 messages unsent. This might explain way 5KB is relatively fast.

I suggest that your reading process is slow and that this is causing its receive buffer to back up, which is causing your send buffer to back up, which stalls your sends.

Or else you haven't written the code correctly for non-blocking mode. If you get a zero result from the write() method, you must (a) change the interestOps to OP_WRITE and (b) return to your select loop. When you get OP_WRITE you must then repeat the write; if you wrote all the data, change the interestOps back to OP_READ, otherwise leave everything as is and wait for the next OP_WRITE. If you attempt to loop while writing in non-blocking mode even in the presence of zero-length writes you will just spin, wasting CPU cycles and time.

Modulo bugs:

while (buffer.position() > 0)
{
  try
  {
    buffer.flip();
    int count = ch.write(buffer);
    if (count == 0)
    {
      key.interestOps(SelectionKey.OP_WRITE);
      break;
    }
  }
  finally
  {
    buffer.compact();
  }
}
if (buffer.position() == 0)
{
  key.interestOps(SelectionKey.OP_READ);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!