Hadoop RPC通信Server端的流程分析

本文主要分析了Hadoop RPC服务端的核心流程,包括Server类定义、三大工作线程的启动以及RPC辅助类的功能。虽然无法涵盖所有细节,但通过源代码解析,概述了主要操作。Hadoop RPC在Java NIO基础上结合动态代理和反射,构建了一个复杂的通信框架。
摘要由CSDN通过智能技术生成

           前2天刚刚小小的分析下Client端的流程,走的还是比较通顺的,但是RPC的服务端就显然没有那么简单了,毕竟C-S这种模式的,压力和重点都是放在Server端的,所以我也只能做个大概的分析,因为里面细节的东西太多,我也不可能理清所有细节,但是我会集合源代码把主要的流程理理清。如果读者想进一步学习的话,可自行查阅源码。

           Server服务端和Client客户端在某些变量的定义上还是一致的,比如服务端也有Call,和Connection,这个很好理解,Call回调,和Connection连接是双向的。首先看一个Server类的定义:

public abstract class Server {
  private final boolean authorize;
  private boolean isSecurityEnabled;
  
  /**
   * The first four bytes of Hadoop RPC connections
   * Hadoop RPC的连接魔数字符‘hrpc’
   */
  public static final ByteBuffer HEADER = ByteBuffer.wrap("hrpc".getBytes());
  
  // 1 : Introduce ping and server does not throw away RPCs
  // 3 : Introduce the protocol into the RPC connection header
  // 4 : Introduced SASL security layer
  public static final byte CURRENT_VERSION = 4;
  ....
这里定义了基本的一些信息,版本号了,还有用于验证的魔数了等等。下面看看他的2个关键内部类,Connection连接和Call回调类

  /** A call queued for handling. */
  /** 服务端的Call列表队列 ,与客户端的是不同的*/
  private static class Call {
	//客户端的Call Id,是从客户端上传过类的
    private int id;                               // the client's call id
    //Call回调参数
    private Writable param;                       // the parameter passed
    //还保存了与客户端的连接
    private Connection connection;                // connection to client
    
    //接收到response回应的时间
    private long timestamp;     // the time received when response is null
                                   // the time served when response is not null
    //对于此回调的回应值
    private ByteBuffer response;                      // the response for this call
    ......
在内部变量的设置上还是有小小的不同的,到时服务端就是通过往Call中写response处理回复的。还有一个是连接类:

  /** Reads calls from a connection and queues them for handling. */
  public class Connection {
	//连接的RPC头部是否已读
    private boolean rpcHeaderRead = false; // if initial rpc header is read
    //版本号之后的头部信息是否已读
    private boolean headerRead = false;  //if the connection header that
                                         //follows version is read.

    private SocketChannel channel;
    //字节缓冲用于读写回复
    private ByteBuffer data;
    private ByteBuffer dataLengthBuffer;
    //回复Call列表
    private LinkedList<Call> responseQueue;
    //此连接下的RPC请求数
    private volatile int rpcCount = 0; // number of outstanding rpcs
    private long lastContact;
    private int dataLength;
    private Socket socket;
    // Cache the remote host & port info so that even if the socket is 
    // disconnected, we can say where it used to connect to.
    private String hostAddress;
    private int remotePort;
    private InetAddress addr;
    .....
上面的变量也很好理解,不解释了,在Server端多出了下面几个关键的变量:

.....
  volatile private boolean running = true;         // true while server runs
  //阻塞式Call待处理的队列
  private BlockingQueue<Call> callQueue; // queued calls

  //与客户端的连接数链表
  private List<Connection> connectionList = 
    Collections.synchronizedList(new LinkedList<Connection>());
  //maintain a list
  //of client connections
  //服务端的监听线程
  private Listener listener = null;
  //处理应答线程
  private Responder responder = null;
  private int numConnections = 0;
  //处理请求线程组
  private Handler[] handlers = null;
  .....
callQueue,待处理请求列表,ConnectionList连接列表,还有3大线程,监听,处理,应答请求线程,待处理请求人家用的还是BlockingQueue阻塞式队列,队列如果满了是插入不了需要等待的,队列为空是取不出数据也是要等待。在这点上作者是有自己的考虑的。通过上面的描述,Server类的大体框图就出来了:


好了,下面的分析重点就是3大线程的具体操作了。3大线程的在Server start操作后就会开始工作:

  /** Starts the service.  Must be called b
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值