如何阻止Flume的HTTP源

时间:2015-02-17 15:30:22

标签: java flume-ng

我正在使用Flume 1.4.0,我试图以某种方式阻止Flume的组件:

  • 首先,停止消息来源。
  • 然后等待,直到通道内的所有事件被水槽消耗。
  • 消耗完所有事件后,停止通道和接收器。

上述任务由关闭钩子执行,就像在org.apache.flume.node.Application中创建的那样(事实上,我正在开发自定义Application)。

我获取源,通道和接收器的方式是:

MaterializedConfiguration conf = configurationProvider.getConfiguration();
ImmutableMap<String, SourceRunner> sourcesRef = conf.getSourceRunners();
ImmutableMap<String, Channel> channelsRef = conf.getChannels();
ImmutableMap<String, SinkRunner> sinksRef = conf.getSinkRunners();

重点是我得到了NullPointerException

2015-02-17 16:03:28,094 (agent-shutdown-hook) [ERROR - org.apache.flume.source.http.HTTPSource.stop(HTTPSource.java:169)] Error while stopping HTTPSource. Exception follows.
java.lang.NullPointerException
    at org.apache.flume.source.http.HTTPSource.stop(HTTPSource.java:165)
    at     org.apache.flume.source.EventDrivenSourceRunner.stop(EventDrivenSourceRunner.java:51)
    at     es.tid.fiware.fiwareconnectors.cygnus.nodes.CygnusApplication$AgentShutdownHook.stopSources(CygnusApplication.java:296)
    at     es.tid.fiware.fiwareconnectors.cygnus.nodes.CygnusApplication$AgentShutdownHook.run(CygnusApplication.java:231)

HTTPSource.java:165是关于停止Jetty服务器实现源的Http服务器部分,这是一个似乎为null的服务器:

162  @Override
163  public void stop() {
164    try {
165      srv.stop();
166      srv.join();
167      srv = null;
168    } catch (Exception ex) {
169      LOG.error("Error while stopping HTTPSource. Exception follows.", ex);
170    }
171    sourceCounter.stop();
172    LOG.info("Http source {} stopped. Metrics: {}", getName(), sourceCounter);
173  }

为什么它为空?源工作正常,并能够接收Http请求。

我猜这不是关闭Flume组件的正确方法......如果不是,那是什么?

谢谢!

2 个答案:

答案 0 :(得分:1)

原因是srv被多个线程共享(因此它是易失性声明)。 Flume尝试调用close来终止源,这种情况不止一次发生。第二次调用stop()失败,因为srv已经无效。

在您的情况下发生这种情况而不是标准香草水槽代理的原因可能是因为您尚未更新SourceCounter。有关详细信息,请查看MonitoredCounterGroup。

答案 1 :(得分:1)

固定。感谢Erik的指针,我对代码进行了调试,直到我意识到每次调用configurationProvider.getConfiguration()句子时都会创建一个新的MaterializedConfiguration。这样的 materialed配置是一整套运行源,通道和接收器。因此,我有几个相同来源的副本......哎呀!然而,不知何故,Flume足够聪明,可以检测到配置的多个具体化,并且我已经看到它关闭了所有重复的组件......但是它包含了Jetty服务器的volatile变量等等。

因此,而不是这样做:

MaterializedConfiguration conf = configurationProvider.getConfiguration();
ImmutableMap<String, SourceRunner> sourcesRef = conf.getSourceRunners();
ImmutableMap<String, Channel> channelsRef = conf.getChannels();
ImmutableMap<String, SinkRunner> sinksRef = conf.getSinkRunners();

现在我在handleConfigurationEvent(MaterializedConfiguration conf)获得了我需要的引用(它被覆盖):

@Override
@Subscribe
public synchronized void handleConfigurationEvent(MaterializedConfiguration conf) {
    sourcesRef = conf.getSourceRunners();
    channelsRef = conf.getChannels();
    sinksRef = conf.getSinkRunners();
    super.handleConfigurationEvent(conf);
} // handleConfigurationEvent

再次感谢Erik!