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

来源:互联网 发布:java 如何做物联网开发 编辑:程序博客网 时间:2024/06/07 21:57

和 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 方法,这个调度问题在之后会说):

@Overridepublic 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;
阅读全文
0 0
原创粉丝点击