dubbo 線程模型

<dubbo:protocol name=“dubbo” dispatcher=“all” threadpool=“fixed” threads=“100” />

Dispatcher

dubbo默認是使用netty的,在初始化NettyServer的構造方法時,對ChannelHandler 進行了包裝。

public NettyServer(URL url, ChannelHandler handler)  {
   super(url, ChannelHandlers.wrap(handler, 
     ExecutorUtil.setThreadName(url, "DubboServerHandler")));
}

最後通過MultiMessageHandler->HeartbeatHandler->通過ExtensionLoader根據配置參數尋找具體的Dispatcher,調用Dispatcher.dispatch得到最終的ChannelHandler

 protected ChannelHandler wrapInternal(ChannelHandler handler, 
  URL url) {
   return new MultiMessageHandler(new HeartbeatHandler(
         ExtensionLoader.getExtensionLoader(Dispatcher.class)
           .getAdaptiveExtension().dispatch(handler, url)));
}

配置還是採用SPI方式.

@SPI(AllDispatcher.NAME)
public interface Dispatcher {
    @Adaptive({Constants.DISPATCHER_KEY, "dispather", 
     "channel.handler"})
    ChannelHandler dispatch(ChannelHandler handler, URL url);
}
@SPI
public interface ChannelHandler {
  /** 連接
  **/
   void connected(Channel channel) ;
   /**斷開連接
   **/
   void disconnected(Channel channel) ;
   /**發送數據
   **/
   void sent(Channel channel, Object message) ;
	/**接收數據
	**/
   void received(Channel channel, Object message) ;
	/**連接出現異常
	**/
   void caught(Channel channel, Throwable exception) ;
}

AllDispatcher(默認all)
在連接、斷開連接、接收數據以及連接出現異常時都是交給線程池去處理的。而發送數據直接交給IO去處理

public class AllDispatcher implements Dispatcher {

    public static final String NAME = "all";

    public ChannelHandler dispatch(ChannelHandler handler, URL url) {
        return new AllChannelHandler(handler, url);
    }

}

在這裏插入圖片描述

public class AllChannelHandler extends WrappedChannelHandler {

    public AllChannelHandler(ChannelHandler handler, URL url) {
        super(handler, url);
    }

    public void connected(Channel channel)  {
        ExecutorService cexecutor = getExecutorService(); 
        try{
            cexecutor.execute(new ChannelEventRunnable(channel, 
            handler ,ChannelState.CONNECTED));
        }catch (Throwable t) {
            throw new ExecutionException();
        }
    }
    
    public void disconnected(Channel channel)  {
        ExecutorService cexecutor = getExecutorService(); 
        try{
            cexecutor.execute(new ChannelEventRunnable(channel, 
             handler ,ChannelState.DISCONNECTED));
        }catch (Throwable t) {
            throw new ExecutionException();
        }
    }

    public void received(Channel channel, Object message) {
        ExecutorService cexecutor = getExecutorService();
        try {
            cexecutor.execute(new ChannelEventRunnable(channel, 
            handler, ChannelState.RECEIVED, message));
        } catch (Throwable t) {
            throw new ExecutionException();
        }
    }

    public void caught(Channel channel, Throwable exception)  {
        ExecutorService cexecutor = getExecutorService(); 
        try{
            cexecutor.execute(new ChannelEventRunnable(channel, 
            handler ,ChannelState.CAUGHT, exception));
        }catch (Throwable t) {
            throw new ExecutionException();
        }
    }

    private ExecutorService getExecutorService() {
        ExecutorService cexecutor = executor;
        if (cexecutor == null || cexecutor.isShutdown()) {
            cexecutor = Executors.newCachedThreadPool(new 
               NamedThreadFactory("DubboSharedHandler", true));
        }
        return cexecutor;
    }
}

而 發送數據則是由父類WrappedChannelHandler,直接交給handler

public void sent(Channel channel, Object message)  {
    handler.sent(channel, message);
}

而線程池初始化也是交給父類去實現的
executor = (ExecutorService) ExtensionLoader.getExtensionLoader(ThreadPool.class).getAdaptiveExtension().getExecutor(url);

DirectDispatcher(direct)
直接交給ChannelHandler去處理
所有消息都不派發到線程池,全部在 IO 線程上直接執行。

public class DirectDispatcher implements Dispatcher {

    public static final String NAME = "direct";

    public ChannelHandler dispatch(ChannelHandler handler,
     URL url) {
        return handler;
    }

}

MessageOnlyChannelHandler(message)
只有在接收數據才交給線程池,別的還是交給ChannelHandler 去處理

public class MessageOnlyChannelHandler extends WrappedChannelHandler {

    public MessageOnlyChannelHandler(ChannelHandler handler, 
      URL url) {
        super(handler, url);
    }

    public void received(Channel channel, Object message) {
        ExecutorService cexecutor = executor;
        if (cexecutor == null || cexecutor.isShutdown()) {
            cexecutor = SHARED_EXECUTOR;
        }
        try {
            cexecutor.execute(new ChannelEventRunnable(channel, 
              handler, ChannelState.RECEIVED, message));
        } catch (Throwable t) {
            throw new ExecutionException();
        }
    }

}

ExecutionChannelHandler(execution)
和All類似

public class ExecutionChannelHandler extends WrappedChannelHandler {
    
    public ExecutionChannelHandler(ChannelHandler handler, URL url) {
        super(handler, url);
    }

    public void connected(Channel channel)  {
        executor.execute(new ChannelEventRunnable(channel, handler ,ChannelState.CONNECTED));
    }

    public void disconnected(Channel channel)  {
        executor.execute(new ChannelEventRunnable(channel, handler ,ChannelState.DISCONNECTED));
    }

    public void received(Channel channel, Object message) {
        executor.execute(new ChannelEventRunnable(channel, handler, ChannelState.RECEIVED, message));
    }

    public void caught(Channel channel, Throwable exception) t {
        executor.execute(new ChannelEventRunnable(channel, handler ,ChannelState.CAUGHT, exception));
    }

}

ConnectionOrderedChannelHandler(connection)
在 IO 線程上,將連接斷開事件放入隊列,有序逐個執行,
其它消息派發到線程池
線程池由自己創建

public class ConnectionOrderedChannelHandler extends WrappedChannelHandler {

    protected final ThreadPoolExecutor connectionExecutor;
    private final int queuewarninglimit ;
    
    public ConnectionOrderedChannelHandler(ChannelHandler handler, URL url) {
        super(handler, url);
        connectionExecutor = new ThreadPoolExecutor(1, 1,
	         0L, TimeUnit.MILLISECONDS,
	         new LinkedBlockingQueue<Runnable>(
	         url.getPositiveParameter(Constants.CONNECT_QUEUE_CAPACITY, 
	            Integer.MAX_VALUE)),
	         new NamedThreadFactory(threadName, true),
	         new AbortPolicyWithReport(threadName, url)
	  );  // FIXME 沒有地方釋放connectionExecutor!
        queuewarninglimit = 
        url.getParameter(Constants.CONNECT_QUEUE_WARNING_SIZE, 
        Constants.DEFAULT_CONNECT_QUEUE_WARNING_SIZE);
    }

    public void connected(Channel channel)  {
        try{
            checkQueueLength();
            connectionExecutor.execute(new ChannelEventRunnable(
             channel, handler ,ChannelState.CONNECTED));
        }catch (Throwable t) {
            throw new ExecutionException();
        }
    }

    public void disconnected(Channel channel){
        try{
            checkQueueLength();
            connectionExecutor.execute(new ChannelEventRunnable(
            channel,  handler ,ChannelState.DISCONNECTED));
        }catch (Throwable t) {
            throw new ExecutionException();
        }
    }

    public void received(Channel channel, Object message){
        ExecutorService cexecutor = executor;
        if (cexecutor == null || cexecutor.isShutdown()) {
            cexecutor = SHARED_EXECUTOR;
        }
        try {
            cexecutor.execute(new ChannelEventRunnable(
             channel, handler, ChannelState.RECEIVED, message));
        } catch (Throwable t) {
            throw new ExecutionException();
        }
    }

    public void caught(Channel channel, Throwable exception)  {
        ExecutorService cexecutor = executor;
        if (cexecutor == null || cexecutor.isShutdown()) { 
            cexecutor = SHARED_EXECUTOR;
        } 
        try{
            cexecutor.execute(new ChannelEventRunnable(channel, 
            handler ,ChannelState.CAUGHT, exception));
        }catch (Throwable t) {
            throw new ExecutionException();
        }
    }
    
    private void checkQueueLength(){
        if (connectionExecutor.getQueue().size() > 
             queuewarninglimit){
            logger.warn(new IllegalThreadStateException());
        }
    }
}

ThreadPool

@SPI("fixed")
public interface ThreadPool {
    
    /**
     * 線程池
     * 
     * @param url 線程參數
     * @return 線程池
     */
    @Adaptive({Constants.THREADPOOL_KEY})
    Executor getExecutor(URL url);

}

FixedThreadPool

固定大小線程池,啓動時建立線程,不關閉,一直持有。(缺省)

/**
 * 此線程池啓動時即創建固定大小的線程數,不做任何伸縮,來源於:<code>Executors.newFixedThreadPool()</code>
 * 
 * @see java.util.concurrent.Executors#newFixedThreadPool(int)
 * @author william.liangf
 */
public class FixedThreadPool implements ThreadPool {

    public Executor getExecutor(URL url) {
        String name = url.getParameter(Constants.THREAD_NAME_KEY, 
           Constants.DEFAULT_THREAD_NAME);
        int threads = url.getParameter(Constants.THREADS_KEY, 
           Constants.DEFAULT_THREADS);
        int queues = url.getParameter(Constants.QUEUES_KEY, 
           Constants.DEFAULT_QUEUES);
        return new ThreadPoolExecutor(threads, threads, 0, 
            TimeUnit.MILLISECONDS, 
        	queues == 0 ? new SynchronousQueue<Runnable>() : 
        			(queues < 0 ? new LinkedBlockingQueue<Runnable>() 
        			: new LinkedBlockingQueue<Runnable>(queues)),
        		new NamedThreadFactory(name, true), 
        		new AbortPolicyWithReport(name, url));
    }

}

**CachedThreadPool **
緩存線程池,空閒一分鐘自動刪除,需要時重建。

/**
 * 此線程池可伸縮,線程空閒一分鐘後回收,新請求重新創建線程,來源於:<code>Executors.newCachedThreadPool()</code>
 * 
 * @see java.util.concurrent.Executors#newCachedThreadPool()
 * @author william.liangf
 */
public class CachedThreadPool implements ThreadPool {

    public Executor getExecutor(URL url) {
        String name = url.getParameter(Constants.THREAD_NAME_KEY, 
          Constants.DEFAULT_THREAD_NAME);
        int cores = url.getParameter(Constants.CORE_THREADS_KEY, 
          Constants.DEFAULT_CORE_THREADS);
        int threads = url.getParameter(Constants.THREADS_KEY,
          Integer.MAX_VALUE);
        int queues = url.getParameter(Constants.QUEUES_KEY,
          Constants.DEFAULT_QUEUES);
        int alive = url.getParameter(Constants.ALIVE_KEY, 
          Constants.DEFAULT_ALIVE);
        return new ThreadPoolExecutor(cores, threads, alive, 
           TimeUnit.MILLISECONDS, 
           queues == 0 ? new SynchronousQueue<Runnable>() : 
        		(queues < 0 ? new LinkedBlockingQueue<Runnable>() 
        					: new LinkedBlockingQueue<Runnable>(queues)),
            new NamedThreadFactory(name, true), 
        	new AbortPolicyWithReport(name, url));
    }

}

LimitedThreadPool
可伸縮線程池,但池中的線程數只會增長不會收縮。
只增長不收縮的目的是爲了避免收縮時突然來了大流量引起的性能問題。

/**
 * 此線程池一直增長,直到上限,增長後不收縮。
 * 
 * @author <a href="mailto:[email protected]">kimi</a>
 */
public class LimitedThreadPool implements ThreadPool {

    public Executor getExecutor(URL url) {
        String name = url.getParameter(Constants.THREAD_NAME_KEY, 
          Constants.DEFAULT_THREAD_NAME);
        int cores = url.getParameter(Constants.CORE_THREADS_KEY, 
           Constants.DEFAULT_CORE_THREADS);
        int threads = url.getParameter(Constants.THREADS_KEY, 
           Constants.DEFAULT_THREADS);
        int queues = url.getParameter(Constants.QUEUES_KEY, 
           Constants.DEFAULT_QUEUES);
        return new ThreadPoolExecutor(cores, threads, Long.MAX_VALUE, TimeUnit.MILLISECONDS, 
        		queues == 0 ? new SynchronousQueue<Runnable>() : 
        			(queues < 0 ? new LinkedBlockingQueue<Runnable>() 
        					: new LinkedBlockingQueue<Runnable>(queues)),
        		new NamedThreadFactory(name, true), new AbortPolicyWithReport(name, url));
    }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章