Flume-NG启动过程源码分析(一)(原创)
从bin/flume 这个shell脚本可以看到Flume的起始于org.apache.flume.node.Application类,这是flume的main函数所在。
main方法首先会先解析shell命令,如果指定的配置文件不存在就甩出异常。
根据命令中含有"no-reload-conf"参数,决定采用那种加载配置文件方式:一、没有此参数,会动态加载配置文件,默认每30秒加载一次配置文件,因此可以动态修改配置文件;二、有此参数,则只在启动时加载一次配置文件。实现动态加载功能采用了发布订阅模式,使用guava中的EventBus实现。
EventBus eventBus = new EventBus(agentName + "-event-bus");
PollingPropertiesFileConfigurationProvider configurationProvider =
new PollingPropertiesFileConfigurationProvider(agentName,
configurationFile, eventBus, 30); //这里是发布事件的类,这里的30则是动态加载配置文件时间间隔,单位是s
components.add(configurationProvider);
application = new Application(components);
eventBus.register(application); //将订阅类注册到Bus中
订阅类是application = new Application(components);发布代码在PollingPropertiesFileConfigurationProvider中的FileWatcherRunnable.run方法中。在这只是先构建一个PollingPropertiesFileConfigurationProvider对象,PollingPropertiesFileConfigurationProvider extends PropertiesFileConfigurationProvider implements LifecycleAware,继续跟踪PropertiesFileConfigurationProvider extends AbstractConfigurationProvider,再跟踪AbstractConfigurationProvider implements ConfigurationProvider可以看到这些类的构造方法都是初始化,AbstractConfigurationProvid的构造方法初始化了sink、channel、source的工厂类。
Application.handleConfigurationEvent(MaterializedConfiguration conf)有@Subscribe注解,是订阅方法,当eventBus.post(MaterializedConfiguration conf)执行时,会触发执行handleConfigurationEvent方法。
new Application(components)时,会构建一个对象supervisor = new LifecycleSupervisor()会启动10个线程用来执行配置文件中的各个组件,并监控组件的整个运行过程。
application.start()方法会启动配置文件的加载过程supervisor.supervise(component, new SupervisorPolicy.AlwaysRestartPolicy(), LifecycleState.START); //LifecycleState.START开始运行,在这的component就是上面的PollingPropertiesFileConfigurationProvider对象。supervise方法会对component创建一个MonitorRunnable进程,并放入默认有10个线程的monitorService去执行
Supervisoree process = new Supervisoree();
process.status = new Status(); process.policy = policy;
process.status.desiredState = desiredState;
process.status.error = false; MonitorRunnable monitorRunnable = new MonitorRunnable();
monitorRunnable.lifecycleAware = lifecycleAware;//组件
monitorRunnable.supervisoree = process;
monitorRunnable.monitorService = monitorService; supervisedProcesses.put(lifecycleAware, process);
//创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟。如果任务的任一执行遇到异常,就会取消后续执行。
ScheduledFuture<?> future = monitorService.scheduleWithFixedDelay(
monitorRunnable, 0, 3, TimeUnit.SECONDS); //启动MonitorRunnable,结束之后3秒再重新启动,可以用于重试
monitorFutures.put(lifecycleAware, future);
看MonitorRunnable类,其run方法主要是根据supervisoree.status.desiredState的值执行对应的操作。这里的lifecycleAware就是上面supervise方法中的component,lifecycleAware在构造之初将lifecycleState=IDLE,application.start()方法通过supervisor.supervise方法将supervisoree.status.desiredState=START。所以在run方法中会执行lifecycleAware.start(),也就是PollingPropertiesFileConfigurationProvider.start()方法。
PollingPropertiesFileConfigurationProvider.start()方法会启动一个单线程FileWatcherRunnable每隔30s去加载一次配置文件(如果配置文件有修改):eventBus.post(getConfiguration())。getConfiguration()是AbstractConfigurationProvider.getConfiguration()这个方法解析了配置文件获取了所有组件及其配置属性。这个方法较为复杂,放在后续再讲解。
待eventBus.post(getConfiguration())之后会触发Application.handleConfigurationEvent方法:
@Subscribe
public synchronized void handleConfigurationEvent(MaterializedConfiguration conf) {
stopAllComponents();
startAllComponents(conf);
}
stopAllComponents()方法会依次stop各个组件的运行,顺序是:source、sink、channel。之所以有顺序是因为:一、source是不停的读数据放入channel的;二、sink是不停的从channel拿数据的,channel两头都在使用应该最后停止,停止向channel发送数据后sink停止才不会丢数据。stop是通过supervisor.unsupervise方法来完成的。
startAllComponents(conf)是启动各个组件的,顺序正好和stopAllComponents()停止顺序相反,相信大伙很容易理解。是通过supervisor.supervise启动组件的。另外需要注意的是启动channel组件后需要等待一定时间,是为了让所有channel全部启动。
另外为什么要先stop再start呢?因为考虑到要动态加载配置文件啊,加载配置文件后就需要重新启动所有组件,所以先停止所有的,再重新启动所有的。
main方法的最后还有一个钩子函数Runtime.getRuntime().addShutdownHook,主要是用来进行内存清理、对象销毁等操作。
欢迎大伙交流
Flume-NG启动过程源码分析(一)(原创)的更多相关文章
- Flume-NG启动过程源码分析(二)(原创)
在上一节中讲解了——Flume-NG启动过程源码分析(一)(原创) 本节分析配置文件的解析,即PollingPropertiesFileConfigurationProvider.FileWatch ...
- Android系统默认Home应用程序(Launcher)的启动过程源码分析
在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还须要有一个Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home应 ...
- Android Content Provider的启动过程源码分析
本文參考Android应用程序组件Content Provider的启动过程源码分析http://blog.csdn.net/luoshengyang/article/details/6963418和 ...
- 10.4 android输入系统_框架、编写一个万能模拟输入驱动程序、reader/dispatcher线程启动过程源码分析
1. 输入系统框架 android输入系统官方文档 // 需FQhttp://source.android.com/devices/input/index.html <深入理解Android 卷 ...
- Spark(五十一):Spark On YARN(Yarn-Cluster模式)启动流程源码分析(二)
上篇<Spark(四十九):Spark On YARN启动流程源码分析(一)>我们讲到启动SparkContext初始化,ApplicationMaster启动资源中,讲解的内容明显不完整 ...
- Spark(四十九):Spark On YARN启动流程源码分析(一)
引导: 该篇章主要讲解执行spark-submit.sh提交到将任务提交给Yarn阶段代码分析. spark-submit的入口函数 一般提交一个spark作业的方式采用spark-submit来提交 ...
- Activity启动过程源码分析(Android 8.0)
Activity启动过程源码分析 本文来Activity的启动流程,一般我们都是通过startActivity或startActivityForResult来启动目标activity,那么我们就由此出 ...
- Netty入门一:服务端应用搭建 & 启动过程源码分析
最近周末也没啥事就学学Netty,同时打算写一些博客记录一下(写的过程理解更加深刻了) 本文主要从三个方法来呈现:Netty核心组件简介.Netty服务端创建.Netty启动过程源码分析 如果你对Ne ...
- Spring启动过程源码分析基本概念
Spring启动过程源码分析基本概念 本文是通过AnnotationConfigApplicationContext读取配置类来一步一步去了解Spring的启动过程. 在看源码之前,我们要知道某些类的 ...
- Netty 启动过程源码分析 (本文超长慎读)(基于4.1.23)
前言 作为一个 Java 程序员,必须知道Java社区最强网络框架-------Netty,且必须看过源码,才能说是了解这个框架,否则都是无稽之谈.今天楼主不会讲什么理论和概念,而是使用debug 的 ...
随机推荐
- 信息搜集之常见的web组合
环境: Win2003或Win7 Asp解析环境搭建 小旋风 Php解析环境搭建 phpstudy aspx解析环境搭建 IIS jsp解析环境搭建 jspstudy 常规渗透环境网络环境解析 1.操 ...
- Extract, Transform, Load
w https://en.wikipedia.org/wiki/Extract,_transform,_load
- JavaScript事件onblur与onfocus区别
一.onblur 1.1 说明 onblur属性在元素失去焦点时触发,onblur常用于表单验证代码(例如用户离开表单字段). 1.2 示例 <input type="text&quo ...
- MiniUI 在线示例
引用 http://miniui.com/demo/#src=datagrid/celledit.html
- 22个所见即所得在线Web编辑器
这些 Web 编辑器可以在线编辑和处理富 Web 内容,包括格式文本,表格,图片,媒体,链接等等,非常适合集成到 CMS网站内容管理系统中使用.本文又搜集了 22 个 Web 在线编辑器,它们基本代表 ...
- zookeeper单机伪集群配置
一.配置 1.在 opt 目录下建一个文件夹 zk,分别把zookeeper 安装包复制三份,命令为zookeeper-0 zookeeper_1 zookeeper_2 2.分别在每一个zook ...
- Oracle学习笔记—oracle体系架构及状态(nomount、mount和open)简介
oracle体系架构简介 先来简要了解一下Oracle数据库体系架构以便于后面深入理解,Oracle Server主要由实例(instance)和数据库(database)组成.实例(instance ...
- numpy的random模块详细解析
随机抽样 (numpy.random) 简单的随机数据 rand(d0, d1, ..., dn) 随机值 >>> np.random.rand(3,2) array([[ 0.14 ...
- 剑指offer 面试26题
面试26题: 题目:树的子结构 题:输入两棵二叉树A和B,判断B是不是A的子结构. 解题思路:递归,注意空指针的情况. 解题代码: # -*- coding:utf-8 -*- # class Tre ...
- django admin基础
通过onetoonefiled扩展得到的不会在添加user是自动添加原因是onetoonefiled只是一个model 可以they are just Django models that happe ...