dubbo的线程派发模型

171 阅读2分钟

这个是dubbo收到IO处理的派发模式

默认使用的是all模式 主要实现就是通过继承WrappedChannelHandler 默认都是使用IO线程池来执行

然后通过重写对应事件的方法来实现 AllChannelHandler就是重写所有的方法 MessageOnlyChannelHandler

就是重写received方法 当有请求和响应的时候就会执行这个方法 会把这个方法传到业务线程池来执行

总共有这些方法可以重写

    /**
     * 连接事件
     */
    void connected(Channel channel) throws RemotingException;

    /**
     * 断开事件
     */
    void disconnected(Channel channel) throws RemotingException;

    /**
     * 心跳发送
     */
    void sent(Channel channel, Object message) throws RemotingException;

    /**
     * 请求响应
     */
    void received(Channel channel, Object message) throws RemotingException;

    /**
     * 异常处理
     */
    void caught(Channel channel, Throwable exception) throws RemotingException;

提供者的话则是所以的事件都是业务线程池来做 也就是默认的200个线程 在2.4.x版本 这里会有个问题 就是当提供者线程池满了以后 received会抛异常 然后会执行caught方法 可以看到下面两个都是抛异常 也就是如果业务线程池一直是满的 会导致无法通知给消费者失败了 消费者只能一直等待 直到超时 在出现大量这种情况下 会导致消费者内存溢出

    public void received(Channel channel, Object message) throws RemotingException {
        ExecutorService cexecutor = getExecutorService();
        try {
            cexecutor.execute(new ChannelEventRunnable(channel, handler, ChannelState.RECEIVED, message));
        } catch (Throwable t) {
            throw new ExecutionException(message, channel, getClass() + " error when process received event .", t);
        }
    }

    public void caught(Channel channel, Throwable exception) throws RemotingException {
        ExecutorService cexecutor = getExecutorService(); 
        try{
            cexecutor.execute(new ChannelEventRunnable(channel, handler ,ChannelState.CAUGHT, exception));
        }catch (Throwable t) {
            throw new ExecutionException("caught event", channel, getClass()+" error when process caught event ." , t);
        }
    }

这时候可以使用message模式 因为message只有重写了received没有重写caught方法 所以会在IO线程池里执行 而IO线程池是无界的 所以会执行 不过这个问题在2.5.X之后已经修复了 当线程池满了以后 会发送消息给消费者线程池满了

    public void received(Channel channel, Object message) throws RemotingException {
        ExecutorService executor = getPreferredExecutorService(message);
        try {
            executor.execute(new ChannelEventRunnable(channel, handler, ChannelState.RECEIVED, message));
        } catch (Throwable t) {
            if(message instanceof Request && t instanceof RejectedExecutionException){
                sendFeedback(channel, (Request) message, t);
                return;
            }
            throw new ExecutionException(message, channel, getClass() + " error when process received event .", t);
        }
    }

参考

www.cnblogs.com/leonxyzh/p/…