Zeppelin 源码分析-Interpreter 相关类(1)

和 Interpreter 直接相关类有以下几个:
Interpreter, InterpreterFactory, RemoteInterpreter, InterpreterGroup, InterpreterSetting。
由于篇幅有限,这里分开介绍。

Interpreter 类及其子类

Interpreter 是一个接口,所有的子类如下(只列举出 SparkInterpreter ):

其中除了 SparkInterpreter 等具体的完成解释功能的类,其余的实现类全部运行在主进程中。

RomoteInterpreter

RomoteInterpreter 类是 SparkInterpreter 等具体的完成解释功能的类的本地代理,其实就可以看成 Thrif 协议的客户端,但是其实这个对象并没有直接持有 Client 类对象的引用,而是在使用 Client 类的时候,用 RemoteInterpreterProcess 对象的方法获得,这在解释器工厂类的 createInterpretersForNote 会详细介绍。
然后比较坑的就是官方那张图:
图片名称
之前一直以为Thrift 的 Server只有一个,但其实程序跑起来之后实际其实应该是这样:

图中的 RemoteInterpreterServer 类是一个线程,并实现了 RemoteInterpreterService.Iface 类,表明这是 Thrif 协议的服务器端( Thrift 协议简单来说就是:有一个 Client 和 Server ,两个运行在不同的 JVM,Server 对外开放指定端口,Client 可以通过服务器开放的端口来调用服务器相应的方法,相应方法在 XXX.thrift 文件中定义,然后可以直接使用 Thirft 官方提供的工具和 XXX.thrift 文件生成指定语言的代码,然后使用时只需要遵循规范实现一些类即可),RemoteInterpreterServer 类中通过反射的方法将具体的解释器进程启动,它和具体的解释器在同一个 JVM 线程中,启动代码如下:

Class<Interpreter> replClass = (Class<Interpreter>) Object.class.forName(className);
Properties p = new Properties();
p.putAll(properties);
setSystemProperty(p);

Constructor<Interpreter> constructor =
    replClass.getConstructor(new Class[] {Properties.class});
Interpreter repl = constructor.newInstance(p);
repl.setClassloaderUrls(new URL[]{});

RomoteInterpreter 类和 RemoteInterpreterServer 类是直接交互的类(依靠 Thrift 协议),当在主进程中调用 RomoteInterpreter 类的 Client 对象的方法时,其实会调用 RemoteInterpreterServer 类的同名的方法,RomoteInterpreter 类存有 RemoteInterpreterProcess 的对象(之后的文件会说这个类),通过这个对象可以获取到 Thrift 的 Client 对象。

SparkInterpreter 等具体实现类

这些类是真正干活的类,前面说过和 RomoteInterpreter 类直接交互的是 RemoteInterpreterServer 类,在 Thrift 客户端调用服务器相应的方法时,服务器端会调用具体的解释器的相应方法,比如 RemoteInterpreterServer 类的 interpret代码如下:(虽然封装成了 Job,但是最终还是调用了 SparkInterpreter 等具体实现类的 interpret 方法,这个调度问题在之后会说):

@Override
public RemoteInterpreterResult interpret(String noteId, String className, String st,
    RemoteInterpreterContext interpreterContext) throws TException {
  // 省略
  Interpreter intp = getInterpreter(noteId, className);
  InterpretJob job = new InterpretJob(
      interpreterContext.getParagraphId(),
      "remoteInterpretJob_" + System.currentTimeMillis(),
      jobListener,
      JobProgressPoller.DEFAULT_INTERVAL_MSEC,
      intp,
      st,
      context);
      }
  // 省略
}
ClassLoaderInterpreter 和 LazyOpenInterpreter

WrappedInterpreter 是一个接口,作用其实就是包装 Interpreter 的实现类,他有两个实现类:ClassLoaderInterpreter 和 LazyOpenInterpreter,该接口的定义如下:

public interface WrappedInterpreter {
  public Interpreter getInnerInterpreter();
}

ClassLoaderInterpreter 其实就是运行在主进程的具体解释器的封装,但是由于目前所有的具体解释器都运行在独立的 JVM 中,因此这个类其实没有什么作用,该类在 InterpreterFactor 被构造,关键代码如下:

// InterpreterFactor 中该类被构造
Class<Interpreter> replClass = (Class<Interpreter>) cl.loadClass(className);
Constructor<Interpreter> constructor =
    replClass.getConstructor(new Class[]{Properties.class});
Interpreter repl = constructor.newInstance(property);
repl.setClassloaderUrls(ccl.getURLs());
LazyOpenInterpreter intp = new LazyOpenInterpreter(new ClassloaderInterpreter(repl, cl));

// InterpreterFactor 类字段
private ClassLoader cl;
private Interpreter intp;

LazyOpenInterpreter 正如其名,其实是对 RomoteInterpreter 的简单封装,存在的意义就是可以延后启动,字段如下:

private Interpreter intp;
volatile boolean opened = false;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值