【问题标题】:What happens when shared MemoryAwareThreadPoolExecutor's threshold is reached?达到共享 MemoryAwareThreadPoolExecutor 的阈值时会发生什么?
【发布时间】:2012-03-24 02:00:25
【问题描述】:

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

我目前的信息状态:

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

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

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

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

【问题讨论】:

    标签: netty


    【解决方案1】:

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

    当达到总阈值时,尝试排队请求的 IO 线程被阻塞,直到处理了足够的数据。您必须非常小心,因为它可能会在以下情况下导致死锁:

    1. 通道(或多个通道)接收数据的速度快于处理速度
    2. 通道(或通道)队列超过总阈值限制,阻塞 IO 线程
    3. 线程池线程将一些数据写回通道并等待它完成。

    线程池线程永远不会被释放,因为IO线程被阻塞等待它返回,因此无法处理写请求。

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

    【讨论】:

      【解决方案2】:

      Channel.setReadable(false) 只会影响调用它的 Channel,不会影响其他通道。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-11
        • 2018-03-03
        • 2015-07-17
        • 2015-02-23
        • 1970-01-01
        相关资源
        最近更新 更多