达到共享MemoryAwareThreadPoolExecutor的阈值时会发生什么?

时间:2012-03-23 14:02:39

标签: netty

当达到MemoryAwareThreadPoolExecutor的频道或总阈值时,频道会发生什么? MemoryAwareThreadPoolExecutor被设置为ExecutionHandler,它位于I / O-Handler之前的每个管道上。

我目前的信息状态:

我发现:channel.setReadable(false)被调用。这意味着所有通道上的所有读操作都会停止,对吧?因此传入的数据不会传递到任何管道,不是吗? 当我做对了你应该在管道的末尾将你的代码分成一个非阻塞的业务处理程序和一个阻塞业务处理程序,在阻塞程序之前使用执行处理程序。 示例: - >解码器,编码,NonBlockingHandler,ExecutionHandler,I / O处理程序

这就是我认为在执行处理程序之前将消息至少发送到最后一个处理程序会更好的地方。如果我是对的,那么在执行处理程序的线程池再次低于阈值之前,I / O处理程序不需要处理的消息将不会进入NonBlockingHandler。

我承认这并不能保证每个频道按收到的顺序执行消息。但是,我们假设没有必要。

对Netty致以最诚挚的问候和欢呼!

2 个答案:

答案 0 :(得分:2)

当达到给定通道的通道阈值时,将调用channel.setReadable(false),从而阻止从该通道进一步读取。当处理了足够的数据时,将调用channel.setReadable(true),允许再次读取数据。与此同时,任何未读数据都将存储在OS网络堆栈缓冲区中或备份到发送主机。

当达到总阈值时,阻止尝试对请求进行排队的IO线程,直到处理了足够的数据。你必须非常小心,因为在下列情况下它会导致死锁:

  1. 频道(或频道)接收数据的速度快于可处理的数据
  2. 通道(或通道)排队超过总阈值限制,阻止IO线程
  3. 线程池线程将一些数据写回通道并等待它完成。
  4. 永远不会释放线程池线程,因为IO线程被阻塞等待它返回,因此无法处理写请求。

    另一件事,除非您在线程池中排队ChannelBuffers,否则您确实需要创建ObjectSizeEstimator的自定义实现,以确保线程池可以正确管理阈值。

答案 1 :(得分:1)

Channel.setReadable(false)只会影响被称为无其他频道的频道。