Hadoop源码学习笔记(2)

——进入main函数打印包信息

找到了main函数,也建立了快速启动的方法,然后我们就进去看一看。

进入NameNode和DataNode的主函数后,发现形式差不多:

  1. public static void main(String args[]) {
  2.     try {
  3.       StringUtils.startupShutdownMessage(DataNode.class, args, LOG);
  4.       DataNode datanode = createDataNode(args, null); //NameNode中类型换成NameNode
  5.       if (datanode != null)
  6.         datanode.join();
  7.     } catch (Throwable e) {
  8.       LOG.error(StringUtils.stringifyException(e));
  9.       System.exit(-1);
  10.     }
  11.   }

进来后第一句是什么,当我们运行到这里时发现:

我们在运行每一个程序时,头上都会在控制台或日志文件中输出这一段话。信息内容主要是描述启动了哪个类,主机,参数,版本,以及编译信息。

跟踪进入StringUtils.startupShutdownMessage类中,

  1. public static void startupShutdownMessage(Class<?> clazz, String[] args,
  2.                                      final org.apache.commons.logging.Log LOG) {
  3.     final String hostname = getHostname();
  4.     final String classname = clazz.getSimpleName();
  5.     LOG.info(
  6.         toStartupShutdownString("STARTUP_MSG: ", new String[] {
  7.             "Starting " + classname,
  8.             " host = " + hostname,
  9.             " args = " + Arrays.asList(args),
  10.             " version = " + VersionInfo.getVersion(),
  11.             " build = " + VersionInfo.getUrl() + " -r "
  12.                          + VersionInfo.getRevision()
  13.                          + "; compiled by '" + VersionInfo.getUser()
  14.                          + "' on " + VersionInfo.getDate()}
  15.         )
  16.       );
  17.  
  18.     Runtime.getRuntime().addShutdownHook(new Thread() {
  19.       public void run() {
  20.         LOG.info(toStartupShutdownString("SHUTDOWN_MSG: ", new String[]{
  21.           "Shutting down " + classname + " at " + hostname}));
  22.       }
  23.     });
  24.   }

在第5行,通过log4j组件进行了输出(这里log4j是一个日志写入组件,对就.net中是log4net,详细就不描述了)。然后前几项类名(className)、主机(hostname)、参数(args)没什么问题,通过应函数取得即可。

其他信息稍后,先看一下第18行,这里是在进程上加了一个勾子,来捕获关闭事件,然后在关闭时,可以输出一下信息,我们可以试下,在控制台运行时,然后按下Ctrl+C终止时,可以看到以下信息:

这段信息,正是第20行代码进行输出的。

其它信息如版本和编译信息呢? 输入内容中是比较细的,它是如何知道的呢? 跟进去看:

  1.   private static HadoopVersionAnnotation version;
  2. static {
  3.     myPackage = HadoopVersionAnnotation.class.getPackage();
  4.     version = myPackage.getAnnotation(HadoopVersionAnnotation.class);
  5.   }
  6.  public static String getUser() {
  7.     return version != null ? version.user() : "Unknown";
  8.   }

这段代码发现getuser是通过一个HadoopVersionAnnotation类的user()函数,而这个HadoopVersionAnnotation发现是一个接口:

  1. @Retention(RetentionPolicy.RUNTIME)
  2. @Target(ElementType.PACKAGE)
  3. public @interface HadoopVersionAnnotation {...}

这个接口是一个比较特殊的接口,在1 2 行可以看到有一特殊标记。我们知道,在java中有些函数上是可以加一个特殊标记的,如@override。而这个override就是一个特殊的标记,它也是一个接口,可以附加在这个函数上,让其具有特殊意义。

而我们的这个HadoopVersionAnnotation就是这样的一个接口,并且它附加在Package上,即用于获取包的信息。

附件在包上的话,这又是在哪呢? 我们在build文件夹找到了:

发现,这里有一个java文件,然后里面定义了包,在包上加了一个@信息,这正是这个接口的定义,同时,在这里传入了版本,编译者,编译时间等信息。于是我们在程序里就可以获取到这里的值了。

但又在想了,这个build文件夹不是一开始没有的么,在运行ant后才创建的么,这个java文件是哪来的?

我们发现,在src文件夹下有saveVersion.sh这么一个文件:

基本可以看出,正是往package-info.java中写入相关信息。

而这个saveVersion.sh可以再追查,在build.xml中有调用。

这个@XXX 其实就是.net中的Attribute称之为特性(属性的属性)。

好的,这个main函数中的第一个砍就算过了。

Hadoop源码学习笔记(2) ——进入main函数打印包信息的更多相关文章

  1. Hadoop源码学习笔记(1) ——第二季开始——找到Main函数及读一读Configure类

    Hadoop源码学习笔记(1) ——找到Main函数及读一读Configure类 前面在第一季中,我们简单地研究了下Hadoop是什么,怎么用.在这开源的大牛作品的诱惑下,接下来我们要研究一下它是如何 ...

  2. Hadoop源码学习笔记(6)——从ls命令一路解剖

    Hadoop源码学习笔记(6) ——从ls命令一路解剖 Hadoop几个模块的程序我们大致有了点了解,现在我们得细看一下这个程序是如何处理命令的. 我们就从原头开始,然后一步步追查. 我们先选中ls命 ...

  3. Hadoop源码学习笔记(5) ——回顾DataNode和NameNode的类结构

    Hadoop源码学习笔记(5) ——回顾DataNode和NameNode的类结构 之前我们简要的看过了DataNode的main函数以及整个类的大至,现在结合前面我们研究的线程和RPC,则可以进一步 ...

  4. Hadoop源码学习笔记(4) ——Socket到RPC调用

    Hadoop源码学习笔记(4) ——Socket到RPC调用 Hadoop是一个分布式程序,分布在多台机器上运行,事必会涉及到网络编程.那这里如何让网络编程变得简单.透明的呢? 网络编程中,首先我们要 ...

  5. Hadoop源码学习笔记(3) ——初览DataNode及学习线程

    Hadoop源码学习笔记(3) ——初览DataNode及学习线程 进入了main函数,我们走出了第一步,接下来看看再怎么走: public class DataNode extends Config ...

  6. Hadoop源码学习笔记之NameNode启动场景流程一:源码环境搭建和项目模块及NameNode结构简单介绍

    最近在跟着一个大佬学习Hadoop底层源码及架构等知识点,觉得有必要记录下来这个学习过程.想到了这个废弃已久的blog账号,决定重新开始更新. 主要分以下几步来进行源码学习: 一.搭建源码阅读环境二. ...

  7. Hadoop源码学习笔记之NameNode启动场景流程四:rpc server初始化及启动

    老规矩,还是分三步走,分别为源码调用分析.伪代码核心梳理.调用关系图解. 一.源码调用分析 根据上篇的梳理,直接从initialize()方法着手.源码如下,部分代码的功能以及说明,已经在注释阐述了. ...

  8. Hadoop源码学习笔记之NameNode启动场景流程二:http server启动源码剖析

    NameNodeHttpServer启动源码剖析,这一部分主要按以下步骤进行: 一.源码调用分析 二.伪代码调用流程梳理 三.http server服务流程图解 第一步,源码调用分析 前一篇文章已经锁 ...

  9. Hadoop源码学习笔记之NameNode启动场景流程五:磁盘空间检查及安全模式检查

    本篇内容关注NameNode启动之前,active状态和standby状态的一些后台服务及准备工作,即源码里的CommonServices.主要包括磁盘空间检查. 可用资源检查.安全模式等.依然分为三 ...

随机推荐

  1. Centos 7.x 安装配置tomcat-8过程梳理

    ----------注意CentOS7.x中的selinux和firewalld都关闭.而且一.二.三部分都是独立的,所以发现8081和8080端口时不要慌哦. 原创,朋友们转载时请著名出处. 一.安 ...

  2. js加密解密 base64

    <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title> ...

  3. PHP消息队列实现

    一个经典的消息队列就是这样的,主要是入队出队操作. shell脚本日志输出 学习地址:http://www.imooc.com/article/19111

  4. [CentOS] 7 不执行文件 /etc/rc.d/rc.local

    chmod 0755 /etc/rc.local systemctl enable rc-local.service --now systemctl restart rc-local.service

  5. 河内塔问题(C++版)

    上次,我们讲了汉诺塔,今天我们来讲一讲和汉诺塔类似的题目<河内塔问题> 题目描述 Description 一位法国数学家曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里 ...

  6. C++默认实参

    某些函数有这样一种形参,在函数的很多次调用中它们都被赋予一个相同的值,此时,我们把这个反复出现的值称为函数的默认实参.调用含有默认实参的函数时,可以包含该实参,也可以省略该实参. 例如定义一个函数sc ...

  7. SBC应用

    在VoIP呼叫中主要使用会话发起协议(SIP),H.323和MGCP呼叫信令协议,Sbc 在主叫和被叫的信令/媒体路径之间引入. 通常,SBC隐藏网络拓扑,接管呼入并生成到新的请求分支到被叫.技术上叫 ...

  8. 20190418 CentOS7实用技能综合:系统安装 + WinScp客户端连接 + 防火墙端口号iptables + Nginx编译安装 + MySQL编译安装 + Redis编译安装 + MongoDB编译安装 + ActiveMQ/RocketMQ/RabbitMQ编译安装 + ...各类常用生产环境软件的编译安装

    系统安装 + WinScp客户端连接 + 防火墙端口号iptables + Nginx编译安装 + MySQL编译安装 + Redis编译安装 + MongoDB编译安装 + ActiveMQ/Roc ...

  9. Kali/Ubuntu无法和物理机之间复制粘贴解决办法

    Vmware安装Linux,传统的vmtools已经被抛弃,当前建议使用Open-VM-tools 安装Open-VM-tools//Kali,Ubuntu: sudo apt install Ope ...

  10. Mac下配置git环境和客户端SourceTree+Git常用命令大全(Mac 10.12)

    前言: 如果不想折腾,直接下载GitHub桌面端,高度集成git,不需要学习git的任何命令. https://desktop.github.com/ 一.配置git环境 1.上官网https://g ...