有时候,通过SocketChannel.write()发送大量数据时,底层TCP缓冲区会被填满,我必须不断重试write(),直到所有数据都被发送。
因此,我可能会有以下代码:
public void send(ByteBuffer bb, SocketChannel sc){
sc.write(bb);
while (bb.remaining()>0){
Thread.sleep(10);
sc.write(bb);
}
}
问题在于大型ByteBuffer和溢出的底层TCP缓冲区偶尔会导致此send()调用阻塞时间超出预期。在我的项目中,有数百个客户端同时连接,一个套接字连接引起的延迟可能会使整个系统陷入瘫痪,直到解决这个SocketChannel的一个延迟。当发生延迟时,它可能会引起其他项目领域的减速连锁反应,因此低延迟非常重要。
我需要一个解决方案,可以在需要多次调用SocketChannel.write()时,透明地处理这个TCP缓冲区溢出问题,而不会造成所有内容都被阻塞。我考虑将send()放入一个扩展线程的单独类中,以便它作为自己的线程运行,并且不会阻塞调用代码。但是,我担心为我维护的每个套接字连接创建一个线程所需的开销,尤其是当99%的情况下,SocketChannel.write()第一次就成功了,这意味着没有必要存在该线程。(换句话说,只有在使用while()循环的情况下,将send()放入单独的线程中才是必要的——仅在存在缓冲区问题的情况下,例如1%的时间)如果只有1%的缓冲区问题,我不需要为其他99%的send()调用产生线程开销。
希望这样解释清楚了……我真的需要一些建议。谢谢!