dubbo源码分析9-- netty创建服务端、客户端以及handler

上一节说到用到这个来创建服务,其实到最后就是new NettyServer(url, listener)

Transporters.bind(url, new DecodeHandler(new HeaderExchangeHandler(handler))

服务端

protected void doOpen() throws Throwable {
    NettyHelper.setNettyLoggerFactory();
    //创建boss线程池
    ExecutorService boss = Executors.newCachedThreadPool(
        new NamedThreadFactory("NettyServerBoss", true));
    //创建worker线程池
    ExecutorService worker = Executors.newCachedThreadPool(new 
        NamedThreadFactory("NettyServerWorker", true));
    ChannelFactory channelFactory = new NioServerSocketChannelFactory(boss, 
        worker, getUrl().getPositiveParameter("iothreads", 
        Runtime.getRuntime().availableProcessors() + 1));
    bootstrap = new ServerBootstrap(channelFactory);
    //处理handler
    final NettyHandler nettyHandler = new NettyHandler(getUrl(), this);
    //将所有的channel保存下来
    channels = nettyHandler.getChannels();
           bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
        public ChannelPipeline getPipeline() {
            NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec() 
            ,getUrl(), NettyServer.this);
            ChannelPipeline pipeline = Channels.pipeline();
            pipeline.addLast("decoder", adapter.getDecoder());
            pipeline.addLast("encoder", adapter.getEncoder());
            pipeline.addLast("handler", nettyHandler);
            return pipeline;
        }
    });
    // bind
    channel = bootstrap.bind(getBindAddress());
}
//关闭服务
 protected void doClose() throws Throwable {
      if (channel != null) 
          channel.close();
      //目前客户端连接的channel全部断开
      Collection<Channel> channels = getChannels();
      if (channels != null && channels.size() > 0) {
          for (com.alibaba.dubbo.remoting.Channel channel : channels) {
           channel.close();
          }
      }
      if (bootstrap != null)
          bootstrap.releaseExternalResources();
      if (channels != null) 
          channels.clear();
    }

客户端

 //创建
 protected void doOpen() throws Throwable {
    NettyHelper.setNettyLoggerFactory();
    bootstrap = new ClientBootstrap(channelFactory);
    bootstrap.setOption("keepAlive", true);
    bootstrap.setOption("tcpNoDelay", true);
    bootstrap.setOption("connectTimeoutMillis", getTimeout());
    final NettyHandler nettyHandler = new NettyHandler(getUrl(), this);
    bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
        public ChannelPipeline getPipeline() {
            NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), 
              getUrl(), NettyClient.this);
            ChannelPipeline pipeline = Channels.pipeline();
            pipeline.addLast("decoder", adapter.getDecoder());
            pipeline.addLast("encoder", adapter.getEncoder());
            pipeline.addLast("handler", nettyHandler);
            return pipeline;
        }
    });
 }
//连接服务端
protected void doConnect() throws Throwable {
   long start = System.currentTimeMillis();
   ChannelFuture future = bootstrap.connect(getConnectAddress());
   try{
       boolean ret = future.awaitUninterruptibly(getConnectTimeout(), 
       TimeUnit.MILLISECONDS);

       if (ret && future.isSuccess()) {
           Channel newChannel = future.getChannel();
           newChannel.setInterestOps(Channel.OP_READ_WRITE);
           try {
               // 关闭旧的连接
               Channel oldChannel = NettyClient.this.channel; 
               if (oldChannel != null) {
                   try {
                       oldChannel.close();
                   } finally {
                       NettyChannel.removeChannelIfDisconnected(oldChannel);
                   }
               }
           } finally {
               if (NettyClient.this.isClosed()) {
                   try {
                       newChannel.close();
                   } finally {
                       NettyClient.this.channel = null;
                       NettyChannel.removeChannelIfDisconnected(newChannel);
                   }
               } else {
                   NettyClient.this.channel = newChannel;
               }
           }
       }
   }finally{
       if (! isConnected()) {
           future.cancel();
       }
   }
}

handler

用来处理netty中的请求。(客户端连接、客户端关闭、接收消息、发送消息以及出现异常)
而在duubo中使用的handler是采用了装饰者模式
这里写图片描述

  • NettyHandler
    主要是将当前客户端连接的channel保存到map中,供NettyServer使用,而他的构造器传进来的ChannelHandler 就是NettyServer(它实现了ChannelHandler)
    NettyHandler nettyHandler = new NettyHandler(getUrl(), this);
public class NettyHandler extends SimpleChannelHandler {
  //在客户端连接服务端,或者断开连接。保存channel
  private final Map<String, Channel> channels = 
  new ConcurrentHashMap<String, Channel>(); 

  private final URL url;

  private final ChannelHandler handler;

  public NettyHandler(URL url, ChannelHandler handler){
      this.url = url;
      this.handler = handler;
  }

  public Map<String, Channel> getChannels() {
      return channels;
  }
  //客户端连接
  public void channelConnected(ChannelHandlerContext ctx, 
      ChannelStateEvent e) throws Exception {
      NettyChannel channel = NettyChannel.getOrAddChannel(ctx.getChannel(), 
          url, handler);
      try {
          if (channel != null) {
              channels.put(NetUtils.toAddressString((InetSocketAddress) 
              ctx.getChannel().getRemoteAddress()), channel);
          }
          handler.connected(channel);
      } finally {
          NettyChannel.removeChannelIfDisconnected(ctx.getChannel());
      }
  }
  //客户端断开
  public void channelDisconnected(ChannelHandlerContext ctx, 
      ChannelStateEvent e) 
      throws Exception {
      NettyChannel channel = NettyChannel.getOrAddChannel(ctx.getChannel(), 
          url, handler);
      try {
          channels.remove(NetUtils.toAddressString((InetSocketAddress) 
              ctx.getChannel().getRemoteAddress()));
          handler.disconnected(channel);
      } finally {
          NettyChannel.removeChannelIfDisconnected(ctx.getChannel());
      }
  }
  //接收客户端的请求,向客户端发送消息,异常处理都是交给handler处理
}
  • AbstractPeer
    这里全部交给下一级的handler处理

  • MultiMessageHandler
    在接收消息时,如果message是MultiMessage类型,那么就循环遍历

public void received(Channel channel, Object message)  {
  if (message instanceof MultiMessage) {
      MultiMessage list = (MultiMessage)message;
      for(Object obj : list) {
          handler.received(channel, obj);
      }
  } else {
      handler.received(channel, message);
  }
}
  • HeartbeatHandler
    主要是记录读写时间,以及在接收消息时,如果是心跳请求,那么就发送消息给对方
 //初始化读写时间
 public void connected(Channel channel)  {
     hannel.setAttribute("READ_TIMESTAMP", System.currentTimeMillis());
     channel.setAttribute("WRITE_TIMESTAMP", System.currentTimeMillis());
     handler.connected(channel);
 }
 //清除读写时间
 public void disconnected(Channel channel) {
     channel.removeAttribute("READ_TIMESTAMP");
     channel.removeAttribute("WRITE_TIMESTAMP");
     handler.disconnected(channel);
 }
 //重设写时间
 public void sent(Channel channel, Object message)  {
     channel.setAttribute("WRITE_TIMESTAMP", System.currentTimeMillis());
     handler.sent(channel, message);
 }
 //重设读时间,如果是心跳请求,那么就发送消息
public void received(Channel channel, Object message) {
    hannel.setAttribute("READ_TIMESTAMP", System.currentTimeMillis());
    //如果消息是心跳请求,那么就发送消息
    if (isHeartbeatRequest(message)) {
        Request req = (Request) message;
        if (req.isTwoWay()) {
            Response res = new Response(req.getId(), req.getVersion());
            res.setEvent(Response.HEARTBEAT_EVENT);
            channel.send(res);
         }
        return;
    }
    //接收消息
    handler.received(channel, message);
}
  • AllChannelHandler
    在线程池中处理这些事件。
public void connected(Channel channel)  {
    ExecutorService cexecutor = getExecutorService();
    cexecutor.execute(new ChannelEventRunnable(channel, handler ,
        ChannelState.CONNECTED));
}

public void disconnected(Channel channel) throws RemotingException {
    ExecutorService cexecutor = getExecutorService(); 
    cexecutor.execute(new ChannelEventRunnable(channel, handler ,
        ChannelState.DISCONNECTED));
}

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

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

//创建线程池
public Executor getExecutor(URL url) {
     String name = url.getParameter(Constants.THREAD_NAME_KEY,  "Dubbo");
     int threads = url.getParameter(Constants.THREADS_KEY, 200);
     int queues = url.getParameter(Constants.QUEUES_KEY, 0);
     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));
 }
  • DecodeHandler
    在接收消息时,对message进行解码
    待后续。。
public void received(Channel channel, Object message)  {
    if (message instanceof Decodeable) 
        decode(message);
    if (message instanceof Request) 
        decode(((Request)message).getData());
    if (message instanceof Response) 
        decode( ((Response)message).getResult());

    handler.received(channel, message);
}
private void decode(Object message) {
    if (message != null && message instanceof Decodeable) 
          ((Decodeable)message).decode();
 }
  • HeaderExchangeHandler
    主要对头部做一些处理

  • ExchangeHandler

private ExchangeHandler requestHandler = new ExchangeHandlerAdapter() {
    //连接
    public void connected(Channel channel) throws RemotingException {
        invoke(channel, "onconnect");
    }

    //关闭连接
    public void disconnected(Channel channel) throws RemotingException {
        invoke(channel, "ondisconnect");
    }

    //接收消息
    public void received(Channel channel, Object message) t {
        if (message instanceof Invocation) {
            reply((ExchangeChannel) channel, message);
        } else {
            super.received(channel, message);
        }
    }

    //执行
    private void invoke(Channel channel, String methodKey) {
        Invocation invocation = createInvocation(channel, channel.getUrl(), 
            methodKey);
        if (invocation != null)
            received(channel, invocation);
    }

//专门处理Invocation的消息
public Object reply(ExchangeChannel channel, Object message)  {
        if (message instanceof Invocation) {
            Invocation inv = (Invocation) message;

            Invoker<?> invoker = getInvoker(channel, inv);

            //如果是callback 需要检查当前的方法是否在url中的methods中...
            RpcContext.getContext().setRemoteAddress(
             channel.getRemoteAddress());
            //直接调用
            return invoker.invoke(inv);
        }
        throw new RemotingException(".....");
    }

    //创建Invocation
    private Invocation createInvocation(Channel channel, 
     URL url, String methodKey) {
        String method = url.getParameter(methodKey);
        if (method == null || method.length() == 0) {
            return null;
        }
        RpcInvocation invocation = 
        new RpcInvocation(method, new Class<?>[0], new Object[0]);
       // ..
        return invocation;
    }
}

//从缓存中获取Invoker
Invoker<?> getInvoker(Channel channel, Invocation inv) {
     boolean isCallBackServiceInvoke = false;
     boolean isStubServiceInvoke = false;
     int port = channel.getLocalAddress().getPort();
     String path = inv.getAttachments().get(Constants.PATH_KEY);

   //如果是客户端的回调服务.
     isStubServiceInvoke = Boolean.TRUE.toString().equals(
         inv.getAttachments().get(Constants.STUB_EVENT_KEY));
     if (isStubServiceInvoke){
         port = channel.getRemoteAddress().getPort();
     }
     //拼接key
     String serviceKey = serviceKey(port, path, 
         inv.getAttachments().get(Constants.VERSION_KEY), 
         inv.getAttachments().get(Constants.GROUP_KEY));

    //从缓存中获取Exporter,在export中创建并exporterMap
     DubboExporter<?> exporter = (DubboExporter<?>) 
         exporterMap.get(serviceKey);

     return exporter.getInvoker();
 }

NettyChannel

这里对客户端传过来的channel进行了封装

final class NettyChannel extends AbstractChannel {

    private NettyChannel(org.jboss.netty.channel.Channel channel, 
       URL url, ChannelHandler handler){
        super(url, handler);
        this.channel = channel;
    }
    //对原有的channel进行封装
    static NettyChannel getOrAddChannel(org.jboss.netty.channel.Channel ch, 
        URL url, ChannelHandler handler) {
        //new NettyChannel然后放进map
        return ret;
    }

    //发送消息
    public void send(Object message, boolean sent)
     throws RemotingException {
        super.send(message, sent);

        boolean success = true;
        int timeout = 0;
        ChannelFuture future = channel.write(message);
        //是否等待
        if (sent) {
            timeout = getUrl().getPositiveParameter("timeout",1000);
            success = future.await(timeout);
        }
        Throwable cause = future.getCause();
        if (cause != null) {
            throw cause;
        }
        if(! success) {
            throw new RemotingException("");
        }
    }
    //...
}

猜你喜欢

转载自blog.csdn.net/liyue1090041509/article/details/80111944