源码是官方提供的最新的Zeppelin0.74版本。
研究了网上很多大神的佳作,和自己的亲身深入体验,尽自己最大努力讲的清楚一点把。
看图说话:
Zeppelin-server:整个系统入口,提供服务器功能、权限认证以及用户校验等功能。该模块中有个ZeppelinServer类,直接run,可以打开localhost:8080,web页面。
InterpreterSetting
维护interpreter相关元信息,维护note与interpreterGroup的关系
Interpreter模块是Zeppelin项目的核心模块,以下为主要的类:
Interpreter
Interpreter是一个抽象类,规定了所有解释器必须实现的功能。所有解释器都要继承这个抽象类,通过不同的具体实现,来完成不同语言的解释执行。
RemoteInterpreterService
此类由Thrift自动生成,定义了主进程与独立JVM解释器进程间的通信协议。
InterpreterGroup
一组Interpreter,用于启动启动和停止解释器JVM的最小单元。
RemoteInterpreterProcess
采用独立JVM启动interpreter的具体执行类
RemoteInterpreter
远程interpreter的本地代理
InterpreterOption
决定Zeppelin创建interpreter进程时的处理方式。
这四个是最主要的模块,剩下的看这个吧,网上大神整理的感觉特别好,刚拿到整个项目时,这个表格可以帮助你快速的了解整个项目的模块功能
名称 | 说明 | 实现语言 |
zeppelin-server | 整个系统入口,提供服务器功能、权限认证以及用户校验等功能 | Java |
zeppelin-zengine | 实现Zeppelin中Notebook的持久化和检索功能 | Java |
zeppelin-interpreter | 执行解释器 | Java |
zeppelin-web | 业务脚本语言编写、数据分析界面、数据可视化与结果导出 | AngularJS |
zeppelin-display | 让前端的AngularJS元素与后台数据进行绑定,进行数据交互 | Scala |
zeppelin-distribution | 用于存放编译后的二进制安装包 | |
zeppelin-examples | 示例代码,用于测试 | |
========================================以上是资源整合部分=====================================
了解这部分源码之前我们先了解一下相关的基本几个类吧:
Paragraph:是执行部件的表现形式,也就是执行的最小单元,对应在web上我们写的代码,我将它比作日记本的每一行字
作用:1:获取代码文本,分离出用户设置的解析器例如%sql,得到相对应解释器的信息,解析用户写的代码段
2:继承Jobl类,代码执行,控制代码过程是开始还是中止,对应用户在web页面上的操作
3:执行结果的返回
note :是notebook的内存对象,zeppelin管理比如持久化,或者共享的最小单元,很多功能与管理Paragraph有关,
对应web上多个代码框,我将它比喻成日记本的一页纸。
notebook:是note的collection,是note的管理者,可以把它看作一个日记本。
作用:1:note的增删改查,克隆,导出,导入
2:维护note和相关解释器的映射,包括note与interpreter的映射,interpreter与具体配置的映射
public class Paragraph extends Job implements Serializable, Cloneable
/* job是一个抽象类,可以控制job的中断,运行等对应着web端的控制,即Paragraph的执行状态受job控制 */
/** * Applicaiton states in this paragraph * 应用程序的状态:loading;unloded;loaded;error * 把每个应用的状态存到了List中 */
private final Listapps = new LinkedList<>();
1: 构造函数:通过构造器,将上面的参数进行初始化,无参的构造器读取系统的默认参数。
2: private static String generateId()//生成一个id,格式为:“paragraph_+时间戳+随机数”作为 paragrathID作为识别
3: public Map
4: public void clearUserParagraphs() //清除内容
5: public static String getRequiredReplName(String text)
/*
根据text内容,将用户引用的解析器名,比如在web端输入%sql 将sql分离出来:先判断text是否以%开头,如果返回null。调用默认的interpreter,
如果不为空,从text开头遍历,遇到回车或者“( ”或者空白字符就停止,然后截取text字段返回给head即为引用的解释器名字
*/
6: public String getScriptBody() //从getRequiredReplName这里的下角标开始截取到最后就是脚本内容了返回text
7: public Interpreter getRepl(String name)
{return factory.getInterpreter(user, note.getId(), name);}
/*
内部是通过
getInterpreterSettings这个方法,获取MapinterpreterBindings>;
而
interpreterBindings里面是个map集合:>
Interpreter的settings里面是interpreterBindings对象,
*/
8:public Interpreter getCurrentRepl() {
return getRepl(getRequiredReplName());
} //通过获取的用户引用的解析器名字,从factory里拿出相对应的解释器
9:public List
这是InterpreterSetting类里的字段内容
10: public List
11:protected boolean jobAbort() { //中止job
12:
public InterpreterContextRunner getInterpreterContextRunner() { /* ParagraphRunner(note对象,noteid,jobid) note里面是对paragraph的一系列解析呀管理呀设置呀包括对应的Interpreter的信息呀,监听等,并且控制paragraph的crut */ return new ParagraphRunner(note, note.getId(), getId());
}
13:重点内部静态类,代码执行的关键地方
static class ParagraphRunner extends InterpreterContextRunner {
private transient Note note;
public ParagraphRunner(Note note, String noteId, String paragraphId) {
super(noteId, paragraphId);
this.note = note;
}
@Override
public void run() {
note.run(getParagraphId());
}
}
这个paragraphrunner类继承了InterpreterContextRunner抽象类,要重写run方法,这个run方法是关键
进入run方法 是note对象的run方法,我们跟踪进入看一下。
到此为止还没完 最后又调用了submit这个方法!!!!这个submit是Scheduler抽象类的抽象方法,我们从他的实现类
FIFOScheduler.submit进去看一下!!!!
剩下的以后抽时间再写吧,写了四个小时了,有些地方还没缕清楚明白,未完待续!