簡體   English   中英

消息大小很大時,socketchannel.write()會變得非常慢

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

在我使用java nio的程序中,當嘗試連續寫入10 KB消息時,socketchannel.write()變得非常慢。 編寫完整的10 KB消息的時間為160毫秒至200毫秒。 但是,編寫完整的5 KB消息所需的時間僅為0.8 ms。

在選擇器中,我只有Selection.OP_READ,不處理Selection.OP_WRITE。 接收到較大的完整消息時,會將其寫入另一個接收者4次。

有人會問同樣的問題嗎? 有一篇關於socketchannel.write()的文章。 我的問題是如何在OP_READ和OP_WRITE之間交替更改?

如果添加一個例如150 ms的間隔,則響應時間會縮短。 有什么辦法可以找到緩沖區何時已滿,以便讓程序等待。 我的操作系統是Windows XP。

謝謝。

我通過檢查寫入的字節數來遵循EPJ的建議。 但是響應時間仍然很高。 我在這里發布了部分代碼,並想檢查我的代碼是否有問題。

//這是使用nio的writeData()部分:

      while (buffer.hasRemaining()) {   
        try {           
                buffer.flip();                  
                n = socket.write(buffer);           
                if(n == 0) {                
                    key.interestOps(SelectionKey.OP_WRITE);
                    key.attach(buffer);             
                    break;
                }                               
        } catch (IOException e) {               
            e.printStackTrace();
        } finally {
            buffer.compact();
        }
    }   

    if(buffer.position()==0) {                  
        key.interestOps(SelectionKey.OP_READ);
    }

我建議您的讀取過程很慢,這將導致其接收緩沖區備份,這將導致您的發送緩沖區備份,從而使發送停止。

否則,您沒有為非阻塞模式正確編寫代碼。 如果從write()方法得到的結果為零,則必須(a)將interestOps更改為OP_WRITE,並且(b)返回到select循環。 當您獲得OP_WRITE時,您必須重復寫入操作; 如果您寫入了所有數據,則將interestOps改回OP_READ,否則將所有內容保持不變,並等待下一個OP_WRITE。 如果您嘗試在非阻塞模式下進行寫操作時進行循環,即使存在零長度寫操作,您也只會旋轉,從而浪費了CPU周期和時間。

模組錯誤:

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);
}

如果寫入時間超過20微秒,則建議您遇到緩沖區已滿的問題。 我假設您正在使用阻止NIO。 當發送緩沖區未滿時,通常需要5到20微秒。 過去,我已將服務器配置為殺死需要2毫秒寫入時間的所有慢速消耗者。 (可能有點激進。)

您可以嘗試增加發送緩沖區的大小(Socket.setSendBufferSize(int),該屬性也可用於SocketChannels),但是看來您正在嘗試發送的數據超出了帶寬的允許范圍。

10 KB不是一條大消息,典型的發送緩沖區大小是64 KB,因此要使其滿,您將需要發送6-7條消息。 這可以解釋5KB的方式相對較快。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM