剖析 azkaban load plugins

插件有很多,azkaban預留的接口多種多樣,比如UserManager,Job,LoginAbstractAzkabanServlet等.

首先我要講的是,jobType插件的加載.jobType只需要由Executor來加載.

executor 配置參數
execution.dir.retention->執行目錄保存時間,單位毫秒,默認一天
azkaban.project.dir->工程運行時存放目錄
azkaban.jobtype.plugin.dir->jobType插件的目錄

public AzkabanExecutorServer(Props props) throws Exception {
    this.props = props;
    server = createJettyServer(props);//創建jetty server

    executionLoader = new JdbcExecutorLoader(props);//executor Dao
    projectLoader = new JdbcProjectLoader(props);//project dao
    runnerManager = new FlowRunnerManager(props, executionLoader, projectLoader, getClass().getClassLoader());//作業流運行管理器

    JmxJobMBeanManager.getInstance().initialize(props);

    // make sure this happens before
    configureJobCallback(props);

    configureMBeanServer();
    configureMetricReports();

    SystemMemoryInfo.init(props.getInt("executor.memCheck.interval", 30));

    loadCustomJMXAttributeProcessor(props);

    try {
      server.start();//啟動jetty server
    } catch (Exception e) {
      logger.error(e);
      Utils.croak(e.getMessage(), 1);
    }

    insertExecutorEntryIntoDB();//往數據庫表進行注冊executor
    dumpPortToFile();

    logger.info("Started Executor Server on " + getExecutorHostPort());

    if (props.getBoolean(ServerProperties.IS_METRICS_ENABLED, false)) {
      startExecMetrics();
    }
  }

jobType管理是在FlowRunnerManager中進行的,在FlowRunnerManager構造函數中創建了
JobTypeManager.

//JobTypeManager構造函數
 public JobTypeManager(String jobtypePluginDir, Props globalProperties,
      ClassLoader parentClassLoader) {
    this.jobTypePluginDir = jobtypePluginDir;//插件目錄,值跟azkaban.properties中azkaban.jobtype.plugin.dir有關
    this.parentLoader = parentClassLoader;
    this.globalProperties = globalProperties;//executor全局屬性配置,是executor.global.properties配置

    loadPlugins();//加載插件
  }

  public void loadPlugins() throws JobTypeManagerException {
    JobTypePluginSet plugins = new JobTypePluginSet();

    loadDefaultTypes(plugins);//加載自帶插件
    if (jobTypePluginDir != null) {
      File pluginDir = new File(jobTypePluginDir);
      if (pluginDir.exists()) {
        logger
            .info("Job type plugin directory set. Loading extra job types from "
                + pluginDir);
        try {
          loadPluginJobTypes(plugins);//加載第三方插件
        } catch (Exception e) {
          logger.info("Plugin jobtypes failed to load. " + e.getCause(), e);
          throw new JobTypeManagerException(e);
        }
      }
    }

以下是JobTypeManager加載第三方的任務類型

private void loadJobTypes(File pluginDir, JobTypePluginSet plugins)
      throws JobTypeManagerException {
    // Directory is the jobtypeName
    String jobTypeName = pluginDir.getName();//目錄名就是任務類型名
    logger.info("Loading plugin " + jobTypeName);

    Props pluginJobProps = null;
    Props pluginLoadProps = null;

    File pluginJobPropsFile = new File(pluginDir, JOBTYPECONFFILE);
    File pluginLoadPropsFile = new File(pluginDir, JOBTYPESYSCONFFILE);

    if (!pluginLoadPropsFile.exists()) {
      logger.info("Plugin load props file " + pluginLoadPropsFile
          + " not found.");
      return;
    }

    try {
      Props commonPluginJobProps = plugins.getCommonPluginJobProps();
      Props commonPluginLoadProps = plugins.getCommonPluginLoadProps();
      if (pluginJobPropsFile.exists()) {
        pluginJobProps = new Props(commonPluginJobProps, pluginJobPropsFile);
      } else {
        pluginJobProps = new Props(commonPluginJobProps);
      }

      pluginLoadProps = new Props(commonPluginLoadProps, pluginLoadPropsFile);
      pluginLoadProps.put("plugin.dir", pluginDir.getAbsolutePath());
      pluginLoadProps = PropsUtils.resolveProps(pluginLoadProps);//替換變量
    } catch (Exception e) {
      logger.error("pluginLoadProps to help with debugging: " + pluginLoadProps);
      throw new JobTypeManagerException("Failed to get jobtype properties"
          + e.getMessage(), e);
    }
    // Add properties into the plugin set
    plugins.addPluginLoadProps(jobTypeName, pluginLoadProps);
    if (pluginJobProps != null) {
      plugins.addPluginJobProps(jobTypeName, pluginJobProps);
    }

    ClassLoader jobTypeLoader =
        loadJobTypeClassLoader(pluginDir, jobTypeName, plugins);
    String jobtypeClass = pluginLoadProps.get("jobtype.class");

    Class<? extends Job> clazz = null;
    try {
      clazz = (Class<? extends Job>) jobTypeLoader.loadClass(jobtypeClass);
      plugins.addPluginClass(jobTypeName, clazz);
    } catch (ClassNotFoundException e) {
      throw new JobTypeManagerException(e);
    }

    logger.info("Verifying job plugin " + jobTypeName);
    try {
      Props fakeSysProps = new Props(pluginLoadProps);
      Props fakeJobProps = new Props(pluginJobProps);
      @SuppressWarnings("unused")
      Job job =
          (Job) Utils.callConstructor(clazz, "dummy", fakeSysProps,
              fakeJobProps, logger);
    } catch (Throwable t) {
      logger.info("Jobtype " + jobTypeName + " failed test!", t);
      throw new JobExecutionException(t);
    }

    logger.info("Loaded jobtype " + jobTypeName + " " + jobtypeClass);
  }

我們可以發現,其中有兩種配置,一個common.properties,一個是commonprivate.properties.
commonprivate.properties是用于在executor加載插件的時候所需要配置參數.common.properties是job啟動的時候需要通用配置參數.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,836評論 18 139
  • 準備工作 Azkaban Web服務器 azkaban-web-server-2.5.0.tar.gz Azkab...
    小馬哥的程序之路閱讀 3,631評論 0 3
  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,925評論 6 342
  • 盒馬購物中心在網上送來5元優惠券,使用規則是購買20元以上生鮮品,期限為三天。 收到優惠券后,我在購物中心買了一公...
    老樂銘閱讀 169評論 0 1
  • 前幾天,寫過一篇文章,談到了格物、致知。記得上高中的歷史書上,寫過宋明理學,其中就有格物致知。那會學歷史是對...
    2016閱讀 177評論 0 0