源码位于Hadoop-common ipc包下

abstract class Server

构造Server

protected Server(String bindAddress, int port,
Class<? extends Writable> rpcRequestClass, int handlerCount,
int numReaders, int queueSizePerHandler, Configuration conf,
String serverName, SecretManager<? extends TokenIdentifier> secretManager,
String portRangeConfig)
throws IOException { //监听地址
this.bindAddress = bindAddress;
this.conf = conf;
this.portRangeConfig = portRangeConfig;
//监听端口
this.port = port;
this.rpcRequestClass = rpcRequestClass;
//处理器个数
this.handlerCount = handlerCount;
this.socketSendBufferSize = 0;
this.maxDataLength = conf.getInt(CommonConfigurationKeys.IPC_MAXIMUM_DATA_LENGTH,
CommonConfigurationKeys.IPC_MAXIMUM_DATA_LENGTH_DEFAULT);
if (queueSizePerHandler != -1) {
this.maxQueueSize = handlerCount * queueSizePerHandler;
} else {
this.maxQueueSize = handlerCount * conf.getInt(
CommonConfigurationKeys.IPC_SERVER_HANDLER_QUEUE_SIZE_KEY,
CommonConfigurationKeys.IPC_SERVER_HANDLER_QUEUE_SIZE_DEFAULT);
}
this.maxRespSize = conf.getInt(
CommonConfigurationKeys.IPC_SERVER_RPC_MAX_RESPONSE_SIZE_KEY,
CommonConfigurationKeys.IPC_SERVER_RPC_MAX_RESPONSE_SIZE_DEFAULT);
if (numReaders != -1) {
this.readThreads = numReaders;
} else {
this.readThreads = conf.getInt(
CommonConfigurationKeys.IPC_SERVER_RPC_READ_THREADS_KEY,
CommonConfigurationKeys.IPC_SERVER_RPC_READ_THREADS_DEFAULT);
}
this.readerPendingConnectionQueue = conf.getInt(
CommonConfigurationKeys.IPC_SERVER_RPC_READ_CONNECTION_QUEUE_SIZE_KEY,
CommonConfigurationKeys.IPC_SERVER_RPC_READ_CONNECTION_QUEUE_SIZE_DEFAULT); // Setup appropriate callqueue
final String prefix = getQueueClassPrefix();
this.callQueue = new CallQueueManager<Call>(getQueueClass(prefix, conf),
getSchedulerClass(prefix, conf),
getClientBackoffEnable(prefix, conf), maxQueueSize, prefix, conf); this.secretManager = (SecretManager<TokenIdentifier>) secretManager;
this.authorize =
conf.getBoolean(CommonConfigurationKeys.HADOOP_SECURITY_AUTHORIZATION,
false); // configure supported authentications
this.enabledAuthMethods = getAuthMethods(secretManager, conf);
this.negotiateResponse = buildNegotiateResponse(enabledAuthMethods); // Start the listener here and let it bind to the port
//监听器
listener = new Listener();
this.port = listener.getAddress().getPort();
connectionManager = new ConnectionManager();
this.rpcMetrics = RpcMetrics.create(this, conf);
this.rpcDetailedMetrics = RpcDetailedMetrics.create(this.port);
this.tcpNoDelay = conf.getBoolean(
CommonConfigurationKeysPublic.IPC_SERVER_TCPNODELAY_KEY,
CommonConfigurationKeysPublic.IPC_SERVER_TCPNODELAY_DEFAULT); this.setLogSlowRPC(conf.getBoolean(
CommonConfigurationKeysPublic.IPC_SERVER_LOG_SLOW_RPC,
CommonConfigurationKeysPublic.IPC_SERVER_LOG_SLOW_RPC_DEFAULT)); // Create the responder here
responder = new Responder(); if (secretManager != null || UserGroupInformation.isSecurityEnabled()) {
SaslRpcServer.init(conf);
saslPropsResolver = SaslPropertiesResolver.getInstance(conf);
} this.exceptionsHandler.addTerseLoggingExceptions(StandbyException.class);
}

Server的主要组成即Listener、

均是单独的线程,底层利用Java NIO实现(Reactor设计模式)  参考NIO系列文章:http://ifeve.com/overview/

如下是创建Listener的源码:

    //创建一个ServerSocketChannel
acceptChannel = ServerSocketChannel.open();
acceptChannel.configureBlocking(false); // Bind the server socket to the local host and port
bind(acceptChannel.socket(), address, backlogLength, conf, portRangeConfig);
port = acceptChannel.socket().getLocalPort(); //Could be an ephemeral port
// create a selector;
selector= Selector.open();
readers = new Reader[readThreads];
for (int i = 0; i < readThreads; i++) {
Reader reader = new Reader(
"Socket Reader #" + (i + 1) + " for port " + port);
readers[i] = reader;
reader.start();
} // Register accepts on the server socket with the selector.
//注册channel到selector
    acceptChannel.register(selector, SelectionKey.OP_ACCEPT);
this.setName("IPC Server listener on " + port);
this.setDaemon(true);

Listener线程通过Selector不断监听请求建立连接的Socket

public void run() {
LOG.info(Thread.currentThread().getName() + ": starting");
SERVER.set(Server.this);
connectionManager.startIdleScan();
while (running) {
SelectionKey key = null;
try {
getSelector().select();
Iterator<SelectionKey> iter = getSelector().selectedKeys().iterator();
while (iter.hasNext()) {
key = iter.next();
iter.remove();
try {
if (key.isValid()) {
if (key.isAcceptable())
doAccept(key);
}
} catch (IOException e) {
}
key = null;
}
} catch (OutOfMemoryError e) {
// we can run out of memory if we have too many threads
// log the event and sleep for a minute and give
// some thread(s) a chance to finish
LOG.warn("Out of Memory in server select", e);
closeCurrentConnection(key, e);
connectionManager.closeIdle(true);
try { Thread.sleep(60000); } catch (Exception ie) {}
} catch (Exception e) {
closeCurrentConnection(key, e);
}
}
LOG.info("Stopping " + Thread.currentThread().getName()); synchronized (this) {
try {
acceptChannel.close();
selector.close();
} catch (IOException e) { } selector= null;
acceptChannel= null; // close all connections
connectionManager.stopIdleScan();
connectionManager.closeAll();
}
}

HADOOP源码分析之RPC(1)的更多相关文章

  1. Hadoop2源码分析-RPC探索实战

    1.概述 在<Hadoop2源码分析-RPC机制初识>博客中,我们对RPC机制有了初步的认识和了解,下面我们对Hadoop V2的RPC机制做进一步探索,在研究Hadoop V2的RPC机 ...

  2. Hadoop源码分析之数据节点的握手,注册,上报数据块和心跳

    转自:http://www.it165.net/admin/html/201402/2382.html 在上一篇文章Hadoop源码分析之DataNode的启动与停止中分析了DataNode节点的启动 ...

  3. SparkRPC源码分析之RPC管道与消息类型

    SparkRPC源码分析之RPC管道与消息类型我们前面看过了netty基础知识扫盲,那我们应该明白,ChannelHandler这个组件内为channel的各种事件提供了处理逻辑,也就是主要业务逻辑写 ...

  4. Hadoop2源码分析-RPC机制初识

    1.概述 上一篇博客,讲述Hadoop V2的序列化机制,这为我们学习Hadoop V2的RPC机制奠定了基础.RPC的内容涵盖的信息有点多,包含Hadoop的序列化机制,RPC,代理,NIO等.若对 ...

  5. Hadoop源码分析之Configuration

    转自:http://www.it165.net/admin/html/201312/2178.html org.apache.hadoop.conf.Configuration类是Hadoop所有功能 ...

  6. Hbase源码分析:RPC概况

    RPC是hbase中Master,RegionServer和Client三者之间通信交流的纽带.了解hbase的rpc机制能够为通过源码学习hbase奠定良好的基础.因为了解了hbase的rpc机制能 ...

  7. hadoop源码分析(2):Map-Reduce的过程解析

    一.客户端 Map-Reduce的过程首先是由客户端提交一个任务开始的. 提交任务主要是通过JobClient.runJob(JobConf)静态函数实现的: public static Runnin ...

  8. Hadoop源码分析之FileSystem抽象文件系统

    Hadopo提供了一个抽象的文件系统模型FileSystem,HDFS是其中的一个实现. FileSystem是Hadoop中所有文件系统的抽象父类,它定义了文件系统所具有的基本特征和基本操作. Fi ...

  9. Hadoop源码分析之产生InputSplit文件过程

        用户提交 MapReduce 作业后,JobClient 会调用 InputFormat 的 getSplit方法 生成 InputSplit 的信息.     一个 MapReduce 任务 ...

随机推荐

  1. 数据结构之合并链表STL

    #include <iostream> #include <list> using namespace std; int main() { int n, m; while (c ...

  2. [2017-09-04]Abp系列——为什么值对象必须设计成不可变的

    本系列目录:Abp介绍和经验分享-目录 这篇是之前翻备忘录发现漏了的,前阵子刚好同事又提及过这个问题,这里补上. 本文重点在于理解什么是值对象的不可变性. Abp的ValueObject以及EF的Co ...

  3. jumpserver-0.3.2 堡垒机环境搭建(图文详解)

    下载安装包:https://github.com/jumpserver/jumpserver.git 解压 三.执行快速安装脚本 cd /opt/jumpserver/install pip inst ...

  4. 再起航,我的学习笔记之JavaScript设计模式19(状态模式)

    状态模式 概念介绍 状态模式(State):当一个对象的内部状态发生改变时,会导致其行为的改变,这看起来像是改变了对象 示例演示 在我们写项目的过程中或多或少会遇到如下的多分支判断 function ...

  5. AJAX 处理xml 数据

    //这个方式返回的得是 xml标准的对象,可以返回 xml字符串,前端js 使用转为xml   function createXml(str){ if(document.all){//IE浏览器 va ...

  6. idea 给maven项目添加依赖(二)

    这里接着上一篇来 我们观察目录发现有两个pom.xml(project object module) 项目是里面的,所以外面的先不管它. 点击里面的pom.xml 1.在<url>节点下面 ...

  7. ServletRequest的一些知识点

    浏览器向服务器的请求(浏览器将数据发送给服务器时,数据存放的地方) 请求方式:GET和POST * GET:发送的数据,追加在请求的URL之上 * POST:发送的数据在HTTP请求体中 浏览器发送数 ...

  8. 【Alpha阶段】第六次scrum meeting

    一.会议照片 二.会议内容 姓名 学号 负责模块 昨日任务完成度 今日任务 杨爱清 099 界面设计和交互功能 完成 设计界面 杨立鑫 100 数据库搭建和其他 完成 将数据库与其他模块连接 林 钊 ...

  9. 201521123111《Java程序设计》第2周学习总结

    1. 本章学习总结 这个星期感觉有点醉,整个人都有点迷茫,仿佛突然失去了方向,连java也难以平复所带来的焦躁的情绪.再加上认为周四早上是没有课的,所以忘记去上了.最近总感觉像咸鱼一样,无所事事,想打 ...

  10. Linux第一篇【介绍、安装Ubuntu、基本目录结构】

    Linux介绍 Linux:不管是不是我们这些学编程的都肯定会听说过这么一个系统,一般地,我们在PC端都是用Windows操作系统,那我们学习Linux操作系统有什么用呢??? 由于我们的JAVAEE ...