【Java】【Flume】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()停止顺序相反。相信大伙非常easy理解。是通过supervisor.supervise启动组件的。另外须要注意的是启动channel组件后须要等待一定时间,是为了让所有channel所有启动。
另外为什么要先stop再start呢?由于考虑到要动态载入配置文件啊。载入配置文件后就须要又一次启动全部组件。所以先停止全部的,再又一次启动全部的。
main方法的最后另一个钩子函数Runtime.getRuntime().addShutdownHook,主要是用来进行内存清理、对象销毁等操作。
【Java】【Flume】Flume-NG启动过程源代码分析(一)的更多相关文章
- Android系统默认Home应用程序(Launcher)的启动过程源代码分析
在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还需要有一个 Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home ...
- Android应用程序组件Content Provider的启动过程源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6963418 通过前面的学习,我们知道在Andr ...
- Activity启动过程源代码分析
事实上写分析源代码文章总会显得非常复杂非常乏味,可是梳理自己看源代码时的一些总结也是一种提高. 这篇博客分析下Activity启动过程源代码,我会尽量说得简单点. 个人的观点是看源代码不能看得太细,否 ...
- Android应用程序启动过程源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6689748 前文简要介绍了Android应用程 ...
- Android 应用程序启动过程源代码分析
本文转自:http://blog.csdn.net/luoshengyang/article/details/6689748 前文简要介绍了Android应用程序的Activity的启动过程.在And ...
- Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6629298 在前面一篇文章浅谈Android系 ...
- Android应用程序绑定服务(bindService)的过程源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6745181 Android应用程序组件Serv ...
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6633311 在上一篇文章中,我 们分析了And ...
- struts2请求过程源代码分析
struts2请求过程源代码分析 Struts2是Struts社区和WebWork社区的共同成果.我们甚至能够说,Struts2是WebWork的升级版.他採用的正是WebWork的核心,所以.Str ...
随机推荐
- nyoj-647-奋斗小蜗牛在请客(进制转换)
奋斗小蜗牛在请客 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描写叙述 一路艰辛一路收获.成功爬过金字塔的小蜗牛别提多高兴了.这不为了向以前帮助他的哥们们表达谢意,蜗牛宴请 ...
- [UVALive 6661 Equal Sum Sets] (dfs 或 dp)
题意: 求从不超过 N 的正整数其中选取 K 个不同的数字,组成和为 S 的方法数. 1 <= N <= 20 1 <= K<= 10 1 <= S <= 15 ...
- Java集合(二):List列表
在上一节中,介绍了Java集合的总体情况.从这节開始,将介绍详细的类.这里不单单介绍类的使用方法.还会试图从源代码的角度分析类的实现.这一节将介绍List接口及实现类.即列表中的链表LinkedLis ...
- win10 bcdedit加入vhdx启动
第一步,先用hyper-v.imagex或者其他vhd安装器.将win10 系统安装到一个vhd文件里(vhdx更好.动态扩展等诸多优良特性).比方d:\win10tp.vhdx 第二步,运行例如以下 ...
- 积跬步,聚小流------java信息生成图片
需求: 是在做证书的时候碰到的这个问题. 当时需求是能够进行在线打印证书,第一次进行的操作是直接打印html,并且已经排好版(用jqprint插件)进行打印.在打印时碰到了兼容的问题,另外因为背景图片 ...
- hdoj--1495--非常可乐(搜索+隐式图)
非常可乐 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- 2017第33周四JDK8并发
Java 8在Lambda表达式.接口默认方式.新的日期API等方面引入的新特性广受关注,同时在并发编程方面也做出了大量改进.以往的几个Java版本都对java.util.concurrent做了不同 ...
- SpringBoot(十一) Dubbo分布式与Zookeeper
Dubbo简介 1.Dubbo简介 1. Dubbo是什么? dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有dubbo这样的分布式服务框架的需求,并且本质上 ...
- 问题集锦 ~ PHP
#switch //当variable为数字0的时候,case为true,会执行第一段case代switch (variable) { case 'value': # code... break; d ...
- SQL where 条件顺序对性能的影响有哪些
经常有人问到oracle中的Where子句的条件书写顺序是否对SQL性能有影响,我的直觉是没有影响,因为如果这个顺序有影响,Oracle应该早就能够做到自动优化,但一直没有关于这方面的确凿证据.在网上 ...