在我的应用程序中,我可以有成千上万的阅读器,每个阅读器都在获取文档。
我需要能够缓冲慢速阅读器,以便我可以继续处理其他阅读器,以便最大限度地使用磁盘和 CPU。
这通常是怎么做的?我当然可以使用 TCP 发送缓冲区,但我认为这些缓冲区会很快填满。
另一种策略是保留一个单独的缓冲区,该缓冲区只是一个有界的 ChannelBuffer 队列。
我假设如果这些缓冲区中的任何一个被填满,我应该让那个客户端失败,因为它读取速度不够快?
在我的应用程序中,我可以有成千上万的阅读器,每个阅读器都在获取文档。
我需要能够缓冲慢速阅读器,以便我可以继续处理其他阅读器,以便最大限度地使用磁盘和 CPU。
这通常是怎么做的?我当然可以使用 TCP 发送缓冲区,但我认为这些缓冲区会很快填满。
另一种策略是保留一个单独的缓冲区,该缓冲区只是一个有界的 ChannelBuffer 队列。
我假设如果这些缓冲区中的任何一个被填满,我应该让那个客户端失败,因为它读取速度不够快?
您正在使用 TCP 发送缓冲区。那是最先填满的东西。然后你开始得到零长度写入。这时你应该做两件事:
在我看来,您还应该在该通道处于状态 2 时停止从该通道读取。如果它仍在产生请求并且没有消耗响应,那是它的问题,而不是您的问题。你没有理由继续产生它没有阅读的回复,也没有理由浪费你的记忆将它们留在身边,直到它决定阅读它们。
我需要能够缓冲慢速阅读器,以便我可以继续处理其他阅读器,以便最大限度地使用磁盘和 CPU。
Netty 真的会为你解决这个问题。由于您是单线程的,因此您不能等待客户端读取任何内容,否则您将锁定单线程并且没有任何反应。所以你可以只写你的ChannelBuffer,它不会阻塞,在你把它返回给netty之后它会稍后发送。因此,在将另一个缓冲区发送或不发送到客户端时,释放您的线程以服务另一个客户端。因此,如果阅读器速度很慢,您最终只会得到一个已填满但未被读取的 ChannelBuffer。
现在,如果客户端确实没有读取某些内容,则您确实有一个 ChannelBuffer(或许多)只是占用了空间,但是如果某些内容花费了太长时间,您可以使用它来通知并清理它:
http://docs.jboss.org/netty/3.1/api/org/jboss/netty/handler/timeout/ReadTimeoutHandler.html
还有这个:
http://docs.jboss.org/netty/3.2/api/org/jboss/netty/handler/timeout/IdleStateHandler.html