[SDU软件工程实践]Blog2-通过脚本文件确定程序入口以及入口部分的初解读

2021SC@SDUSC


在上一次博客中,我有说过我是负责第一部分——从HQL语句转化至抽象语法树AST这一步。而由于这一部分是第一部分,所以我要从命令行开始,理清程序的执行路径。

$ bin/hive开始

为什么是hive

我们开启HQL命令行的指令就是bin/hive,我们前往源代码,可以发现我们执行的这个名为hive的脚本文件
这个hive就是我们的开始
据我所知,hiveserver2也是一个入口,不过我发现这个hiveserver2的内部是这个样子的:
主要看最后面
也就是说它也是执行了hive这个脚本,所以我们着重关注hive就可以了

hive都做了什么

hive里面有非常多的条件判断、变量设置等等等等。其中相当一部分都是对环境的检查,源代码里就有注释。这帮助我省去了非常多的工作。而且我的思路是:优先观察这个脚本执行了什么文件。于是我将范围锁定在了以下代码:

  26   . "$bin"/hive-config.sh
       …………
       …………
 100   if [ -f "${HIVE_CONF_DIR}/hive-env.sh" ]; then
 101     . "${HIVE_CONF_DIR}/hive-env.sh"
       …………
       …………
 314   for i in "$bin"/ext/*.sh ; do
 315    . $i
 316   done
 317
 318   for i in "$bin"/ext/util/*.sh ; do
 319    . $i
 320   done

我首先将前两个排除了,这两个都明显是偏配置向的。
最后一个是在执行/ext文件夹内的所有的脚本文件:
我第一眼看到的时候极度不悦……
不过好在这些文件名称是有意义的,cli.sh指明这是命令行的脚本,cli是“command line interface”的缩写,于是我追到这个文件中:
CliDriver
这个脚本文件指向了这样一个类:
org.apache.hadoop.hive.cli.CliDriver
我们终于接近源代码了

走进CliDriver

看来执行的开端就是CliDriver这个类了

main方法

我在CliDriver中进行概览,看看有没有main方法
main
很好!这个类里存在一个main方法,我相信这是我们的入口。沿着这个代码,我们可以继续前往run方法

run方法及它进行的调用

oproc?
这是第一个问题:oproc是干什么的?我去追索了OptionsProcessor这个类(虽然这个类的功能从类的名字上能有所猜测,但是还是去看了一下)
OptionsProcessor中的process_stage1(String)这个方法
主要是GnuParser和commandLine值得注意
其中,commandLine所属类CommandLineGnuParser这两个类都已经不是hive内的了,它们属于org.apache.commons.cli这个包。这说明它们极有可能属于apache的基础框架的一部分。虽然我不打算展开深究了,但是我还是沿着GnuParser到其父类Parser看了一眼:
看到"--"和"-"了吗
基本可以推断,这一系列的操作是用于解析命令行输入的命令的,而org.apache.commons.cli这个包很可能是一个用于解析命令行的框架(事实似乎确实如此)
而从process_stage1(String)这个方法内部的其他操作来看,这个方法处理了输入的字符串,并且将字符串解析的结果存入了类中的一个Map里,我推断这个存储的操作有可能在后续用到,比如有方法会调用这个解析好的命令之类的。总之oproc一定不是只用于验证的。
这个方法本身也利用commandLine来进行一些操作,可能是一些系统配置吧
我们继续看。
中间跳过一个log4j的初始化(反正就是个很重要的初始化)
这块就很厉害……
我们要注意这两块:

    CliSessionState ss = new CliSessionState(new HiveConf(SessionState.class));
    if (!oproc.process_stage2(ss)) {
      return 2;
    }

ss是牵扯到流的,它的流附上了各种标准流。而且它被作为process_stage2(CliSessionState)的参数,我们可以向内看一看:
底下还有一小点代码,和上面做的事差不多
这里呀我们要注意了,执行这个方法的是前面的oproc这个对象,在之前调用process_stage1(String)时,commandLine这个变量已经被初始化了,它是解析我们打开HQL客户端时的命令行命令的结果。而在process_stage2(CliSessionState)中,利用commandLiness来进行一些配置。而这一次我可以明确看出这些操作的用处了:-e-f这些都是在命令行执行hive这个脚本的可用参数啊!这一步应该是在对这些用户输入的参数进行解析与执行。


这里有一个插曲:我看到ss.getConf()的时候就去找了找,发现这个方法返回的是一个sessionConf的属性,这个属性来自于CliSessionState ss = new CliSessionState(new HiveConf(SessionState.class))这里,CliSessionState的构造方法是这样的:

  public CliSessionState(HiveConf conf) {
    super(conf);
  }

这个类又是继承自SessionState这个类的……好我们继续挖,这个类的构造方法长这个样子

  public SessionState(HiveConf conf) {
    this(conf, null);
  }

然后它调用的另一个构造方法是

  public SessionState(HiveConf conf, String userName) {
    this.sessionConf = conf;
    ………………
    ………………

好,也就是说getConf()的来源是new HiveConf(SessionState.class),这里就又是一大堆东西了。
但后来我意识到getConf()这个方法的返回值并没有被接收,我不太能理解,这后面的内容也就不再深究了。


后面有好几个给出了注释的操作,这些操作包括:利用ss.getConf()的结果进行配置,SessionState的启动(这是一个有关会话、公共数据、线程等内容的类)等等

在这个方法的最后是这样的一段
这就是最后了
它调用了另一个叫executeDriver的方法。这个方法将之前的操作的核心:ssconf(来自ss.getConf()),oproc全部传下了。

总结

我们通过脚本文件找到了CliDriver,并且发现它第一个执行的是run方法。我们发现run方法进行了大量和配置相关的操作,显然这仍然是一系列前置操作。而executeDriver则是我们接下来需要继续探查的路线了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值