dubbo中netty业务线程池的使用

前言

dubbo底层通讯使用的是netty,下面介绍下dubbo中使用netty业务线程池的使用。

一.业务线程池

为什么需要业务线程池?直接使用netty的io线程处理非耗时链接是ok的;如果业务有数据库,调用第三方接口等耗时操作,就会阻塞住io线程,导致其他的io线程得不到及时的处理,造成阻塞导致客户端超时。所以对于耗时操作,扔到业务线程池,释放io线程去处理其他连接。

二.源码解析

源码是dubbo3.1

服务端接受到请求的链路

received()方法:netty pipeline链路,NettyServerHandler自定义handler

IO线程:

NettyServerHandler=>AbstractPeer=>MultiMessageHandler=>HeartbeatHandler=>AllChannelHandler(获取业务线程池)

业务线程:              

 ChannelEventRunnable=>DecodeHandler=>HeaderExchangeHandler=>DubboProtocol$ExchangeHandlerAdapter=>  《invoke filter chain》 => real method

中间都是一些链路逻辑处理,重点看看AllChannelHandler

    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);
        }
    }

这个方法getPreferredExecutorService获取线程池:

    /**
     * Currently, this method is mainly customized to facilitate the thread model on consumer side.
     * 1. Use ThreadlessExecutor, aka., delegate callback directly to the thread initiating the call. //客户端使用ThreadlessExecutor,发起调用的线程执行
     * 2. Use shared executor to execute the callback. //服务端用线程池
     *
     * @param msg
     * @return
     */
    public ExecutorService getPreferredExecutorService(Object msg) {
        if (msg instanceof Response) {
            Response response = (Response) msg;
            DefaultFuture responseFuture = DefaultFuture.getFuture(response.getId());
            // a typical scenario is the response returned after timeout, the timeout response may have completed the future
            if (responseFuture == null) {
                return getSharedExecutorService();
            } else {
                ExecutorService executor = responseFuture.getExecutor();
                if (executor == null || executor.isShutdown()) {
                    executor = getSharedExecutorService();
                }
                return executor;
            }
        } else {
            return getSharedExecutorService();
        }
    }

1.如果是客户端处理response,未超时情况下使用ThreadlessExecutor;超时了可能处理了等待的future,使用共享线程池;

2.如果是服务端,使用共享线程池;

这个区别是客户端使用当前发起调用的线程执行返回结果,减少线程切换;服务端则需要放入线程池执行,防止阻塞io线程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值