Flume Source&SourceRunner 介绍

Flume Source&SourceRunner 介绍

Source 作为Flume 的数据接收源 source 有两个子类 PollableSourceEventDrivenSource

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xf1LU4dW-1571214286033)(https://i.ibb.co/cb2hSxX/TIM-20191016154243.png)]

但是 Source 的启动主要依靠的是 SourceRunner 启动的,同样SourceRunner 分为 PollableSourceRunnerEventDrivenSourceRunner

SourceRunner

根据source获取到SourceRunner

public static SourceRunner forSource(Source source) {
    SourceRunner runner = null;

    if (source instanceof PollableSource) {
        runner = new PollableSourceRunner();
        ((PollableSourceRunner) runner).setSource((PollableSource) source);
    } else if (source instanceof EventDrivenSource) {
        runner = new EventDrivenSourceRunner();
        ((EventDrivenSourceRunner) runner).setSource((EventDrivenSource) source);
    } else {
        throw new IllegalArgumentException("No known runner type for source "
            + source);
    }

    return runner;
}

PollableSource & PollableSourceRunner 轮询机制

PollableSourceRunner

  @Override
  public void start() {
    PollableSource source = (PollableSource) getSource();
    ChannelProcessor cp = source.getChannelProcessor();
    cp.initialize();
    source.start();

    runner = new PollingRunner();

    runner.source = source;
    runner.counterGroup = counterGroup;
    runner.shouldStop = shouldStop;

    // 轮询模式启动了一个线程去执行
    runnerThread = new Thread(runner);
    runnerThread.setName(getClass().getSimpleName() + "-" + 
        source.getClass().getSimpleName() + "-" + source.getName());
    runnerThread.start();

    lifecycleState = LifecycleState.START;
  }

public static class PollingRunner implements Runnable {

    private PollableSource source;
    private AtomicBoolean shouldStop;
    private CounterGroup counterGroup;

    @Override
    public void run() {
      logger.debug("Polling runner starting. Source:{}", source);

      // 只要为被关闭就死循环的执行  
      while (!shouldStop.get()) {
        counterGroup.incrementAndGet("runner.polls");

        try {
          // source#process 应该是核心的业务逻辑
          if (source.process().equals(PollableSource.Status.BACKOFF)) {
            counterGroup.incrementAndGet("runner.backoffs");

            Thread.sleep(Math.min(
                counterGroup.incrementAndGet("runner.backoffs.consecutive")
                * backoffSleepIncrement, maxBackoffSleep));
          } else {
            counterGroup.set("runner.backoffs.consecutive", 0L);
          }
        } catch (InterruptedException e) {
          logger.info("Source runner interrupted. Exiting");
          counterGroup.incrementAndGet("runner.interruptions");
        } catch (EventDeliveryException e) {
          logger.error("Unable to deliver event. Exception follows.", e);
          counterGroup.incrementAndGet("runner.deliveryErrors");
        } catch (Exception e) {
          counterGroup.incrementAndGet("runner.errors");
          logger.error("Unhandled exception, logging and sleeping for " +
              maxBackoffSleep + "ms", e);
          try {
            Thread.sleep(maxBackoffSleep);
          } catch (InterruptedException ex) {
            Thread.currentThread().interrupt();
          }
        }
      }

      logger.debug("Polling runner exiting. Metrics:{}", counterGroup);
    }

  }

public interface PollableSource extends Source {
  /**
   * <p>
   * Attempt to pull an item from the source, sending it to the channel.
   * </p>
   * <p>
   * When driven by an {@link EventDrivenSourceRunner} process is guaranteed
   * to be called only by a single thread at a time, with no concurrency.
   * Any other mechanism driving a pollable source must follow the same
   * semantics.
   * </p>
   * @return {@code READY} if one or more events were created from the source.
   * {@code BACKOFF} if no events could be created from the source.
   * @throws EventDeliveryException If there was a failure in delivering to
   * the attached channel, or if a failure occurred in acquiring data from
   * the source.
   */
   /**
    * <p>
    *尝试从源中提取项目,然后将其发送到频道。
    * </ p>
    * <p>
    *由{@link EventDrivenSourceRunner}进程驱动时,可以保证
    *一次只能由单个线程调用,没有并发。
    *任何其他驱动可轮询源的机制都必须遵循相同的原则
    *语义。
    * </ p>
    * @return {@code READY}(如果源中创建了一个或多个事件)。
    * {@code BACKOFF}如果无法从源创建任何事件。
    * @throws EventDeliveryException如果传递到
    *连接的通道,或者从以下通道获取数据失败
    * 来源。
    **/
  public Status process() throws EventDeliveryException;

  public static enum Status {
    READY, BACKOFF
  }

}

EventDrivenSource & EventDrivenSourceRunner 事件驱动

EventDrivenSourceRunner

  @Override
  public void start() {
    Source source = getSource();
    ChannelProcessor cp = source.getChannelProcessor();
    cp.initialize();
    source.start();
    lifecycleState = LifecycleState.START;
  }

这个SourceRunner就比较简单,直接吧内部的source启动就完事了

因为sourceRunner内部没有启动额外线程监听事件,所以EventDrivenSource通常需要在start方法内部启动额外线程去执行操作

ExecSource

  @Override
  public void start() {
    logger.info("Exec source starting with command:{}", command);

    executor = Executors.newSingleThreadExecutor();
    //使用线程池提交了一个新的runnable 在start内部启动新的线程执行监听操作
    runner = new ExecRunnable(shell, command, getChannelProcessor(), sourceCounter,
        restart, restartThrottle, logStderr, bufferCount, batchTimeout, charset);

    runnerFuture = executor.submit(runner);

    sourceCounter.start();
    super.start();

    logger.debug("Exec source started");
  }

    public void run() {
        do {
        ...
        try {
            ...
            synchronized (eventList) {
                if(!eventList.isEmpty()) {
                flushEventBatch(eventList);
                }
            }
        } catch (Exception e) {
            ...
        } finally {
            ...
        }
        if(restart) {
            ...;
        }
        // 当执行stop 方法时 restart 设置为 false 也是一个死循环的处理
        } while(restart);
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值