public JobLoggerDelegate(Config config) {
    JobLoggerFactory jobLoggerFactory =
        ExtensionLoader.getExtensionLoader(JobLoggerFactory.class).getAdaptiveExtension();
    jobLogger = jobLoggerFactory.getJobLogger(config);
    lazyLog = config.getParameter(Constants.LAZY_JOB_LOGGER, false);
    if (lazyLog) {

      // 无界Queue
      memoryQueue = new LinkedBlockingQueue<JobLogPo>();
      maxMemoryLogSize = config.getParameter(Constants.LAZY_JOB_LOGGER_MEM_SIZE, 1000);
      flushPeriod = config.getParameter(Constants.LAZY_JOB_LOGGER_CHECK_PERIOD, 3);

      executor =
          Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("LazyJobLogger"));
      scheduledFuture =
          executor.scheduleWithFixedDelay(
              new Runnable() {
                @Override
                public void run() {
                  try {
                    if (flushing.compareAndSet(false, true)) {
                      checkAndFlush();
                    }
                  } catch (Throwable t) {
                    LOGGER.error("CheckAndFlush log error", t);
                  }
                }
              },
              flushPeriod,
              flushPeriod,
              TimeUnit.SECONDS);
    }
  }
/** @author Robert HG ([email protected]) on 8/15/14. 抽象节点 */
public abstract class AbstractJobNode<T extends Node, App extends Application> implements JobNode {

  protected static final Logger LOGGER = LoggerFactory.getLogger(JobNode.class);

  protected Registry registry;
  protected T node;
  protected Config config;
  protected App application;
  private List<NodeChangeListener> nodeChangeListeners;
  private List<MasterChangeListener> masterChangeListeners;
  private EventCenterFactory eventCenterFactory =
      ExtensionLoader.getExtensionLoader(EventCenterFactory.class).getAdaptiveExtension();
  private AtomicBoolean started = new AtomicBoolean(false);

  public AbstractJobNode() {
    application = getApplication();
    config = JobNodeConfigFactory.getDefaultConfig();
    application.setConfig(config);
    nodeChangeListeners = new ArrayList<NodeChangeListener>();
    masterChangeListeners = new ArrayList<MasterChangeListener>();
  }

  public final void start() {
    try {
      if (started.compareAndSet(false, true)) {
        // 初始化配置
        initConfig();

        preRemotingStart();

        remotingStart();

        afterRemotingStart();

        initRegistry();

        registry.register(node);

        LOGGER.info("Start success!");
      }
    } catch (Throwable e) {
      LOGGER.error("Start failed!", e);
    }
  }

  public final void stop() {
    try {
      if (started.compareAndSet(true, false)) {

        registry.unregister(node);

        preRemotingStop();

        remotingStop();

        afterRemotingStop();

        LOGGER.info("Stop success!");
      }
    } catch (Throwable e) {
      LOGGER.error("Stop failed!", e);
    }
  }

  @Override
  public void destroy() {
    try {
      registry.destroy();
      LOGGER.info("Destroy success!");
    } catch (Throwable e) {
      LOGGER.error("Destroy failed!", e);
    }
  }

  protected void initConfig() {
    application.setEventCenter(eventCenterFactory.getEventCenter(config));

    application.setCommandBodyWrapper(new CommandBodyWrapper(config));
    application.setMasterElector(new MasterElector(application));
    application.getMasterElector().addMasterChangeListener(masterChangeListeners);
    application.setRegistryStatMonitor(new RegistryStatMonitor(application));

    node = NodeFactory.create(getNodeClass(), config);
    config.setNodeType(node.getNodeType());

    LOGGER.info("Current node config :{}", config);

    // 订阅的node管理
    SubscribedNodeManager subscribedNodeManager = new SubscribedNodeManager(application);
    application.setSubscribedNodeManager(subscribedNodeManager);
    nodeChangeListeners.add(subscribedNodeManager);
    // 用于master选举的监听器
    nodeChangeListeners.add(new MasterElectionListener(application));
    // 监听自己节点变化(如,当前节点被禁用了)
    nodeChangeListeners.add(new SelfChangeListener(application));
  }

  private void initRegistry() {
    registry = RegistryFactory.getRegistry(application);
    if (registry instanceof AbstractRegistry) {
      ((AbstractRegistry) registry).setNode(node);
    }
    registry.subscribe(
        node,
        new NotifyListener() {
          private final Logger NOTIFY_LOGGER = LoggerFactory.getLogger(NotifyListener.class);

          @Override
          public void notify(NotifyEvent event, List<Node> nodes) {
            if (CollectionUtils.isEmpty(nodes)) {
              return;
            }
            switch (event) {
              case ADD:
                for (NodeChangeListener listener : nodeChangeListeners) {
                  try {
                    listener.addNodes(nodes);
                  } catch (Throwable t) {
                    NOTIFY_LOGGER.error(
                        "{} add nodes failed , cause: {}",
                        listener.getClass().getName(),
                        t.getMessage(),
                        t);
                  }
                }
                break;
              case REMOVE:
                for (NodeChangeListener listener : nodeChangeListeners) {
                  try {
                    listener.removeNodes(nodes);
                  } catch (Throwable t) {
                    NOTIFY_LOGGER.error(
                        "{} remove nodes failed , cause: {}",
                        listener.getClass().getName(),
                        t.getMessage(),
                        t);
                  }
                }
                break;
            }
          }
        });
  }

  protected abstract void remotingStart();

  protected abstract void remotingStop();

  protected void preRemotingStart() {
    // 检查identity是否重复

  }

  protected void afterRemotingStart() {}

  protected void preRemotingStop() {}

  protected void afterRemotingStop() {}

  @SuppressWarnings("unchecked")
  private App getApplication() {
    try {
      return ((Class<App>) GenericsUtils.getSuperClassGenericType(this.getClass(), 1))
          .newInstance();
    } catch (InstantiationException e) {
      throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
      throw new RuntimeException(e);
    }
  }

  @SuppressWarnings("unchecked")
  private Class<T> getNodeClass() {
    return (Class<T>) GenericsUtils.getSuperClassGenericType(this.getClass(), 0);
  }

  /** 设置zookeeper注册中心地址 */
  public void setRegistryAddress(String registryAddress) {
    config.setRegistryAddress(registryAddress);
  }

  /** 设置远程调用超时时间 */
  public void setInvokeTimeoutMillis(int invokeTimeoutMillis) {
    config.setInvokeTimeoutMillis(invokeTimeoutMillis);
  }

  /** 设置集群名字 */
  public void setClusterName(String clusterName) {
    config.setClusterName(clusterName);
  }

  /** 节点标识(必须要保证这个标识是唯一的才能设置,请谨慎设置) 这个是非必须设置的,建议使用系统默认生成 */
  public void setIdentity(String identity) {
    config.setIdentity(identity);
  }

  /** 添加节点监听器 */
  public void addNodeChangeListener(NodeChangeListener notifyListener) {
    if (notifyListener != null) {
      nodeChangeListeners.add(notifyListener);
    }
  }

  /** 添加 master 节点变化监听器 */
  public void addMasterChangeListener(MasterChangeListener masterChangeListener) {
    if (masterChangeListener != null) {
      masterChangeListeners.add(masterChangeListener);
    }
  }

  /** 设置额外的配置参数 */
  public void addConfig(String key, String value) {
    config.setParameter(key, value);
  }
}