1. 程式人生 > >如何在程式裡動態載入配置檔案

如何在程式裡動態載入配置檔案

flume的sink程序或者kafka的consumer程序,特定的時候需要讀取配置檔案,如提取指定的欄位或過濾指定欄位等。這種情況,若沒有動態載入,則需要需改程式碼或配置檔案,重啟程序方能生效,十分不利於維護。最好的辦法是讓程序去監控配置檔案的改動,然後動態的去讀取其中的內容並應用到程序中去,從而達到動態修改。

方案就是啟動一個單獨執行緒去監控配置檔案的最後修改時間,若發現有改動則重新載入。

程式碼如下:

public class ReloadThread extends Thread {

  private static final Logger log = LoggerFactory.getLogger(ReloadThread.class);

  private long lastSuccessfulReload;
  private File configureFile;
  public List<String> selectedFields;

  public ReloadThread(File configureFile) {
    this.configureFile = configureFile;
    selectedFields = new ArrayList<String>();
  }

  public String getSelectedFields() {
    StringBuilder sb = new StringBuilder();
    for (String item : selectedFields) {
      sb.append(item).append(",");
    }
    if (sb.length() > 0) {
      return (sb.substring(0, sb.length() - 1));
    } else {
      return "";
    }
  }

  @Override
  public void run() {
    while (true) {
      long time = System.currentTimeMillis();
      long lastModified = configureFile.lastModified();
      if (lastModified > lastSuccessfulReload
          && time > lastModified + KafkaUtil.ALLOC_RELOAD_WAIT_MS) {
        try {
          synchronized (selectedFields) {
            reloadConfigureFile(configureFile);
            log.info("Reload configuration file: " + getSelectedFields());
            lastSuccessfulReload = System.currentTimeMillis();
          }
        } catch (Exception ex) {
          log.error(
              "Failed to reload config file - will use existing configuration.",
              ex);
        }
      }
    }
  }

  public void reloadConfigureFile(File configureFile) {
    try {
      /** 判斷檔案是否存在 */
      if (configureFile.isFile() && configureFile.exists()) {
        InputStreamReader read = new InputStreamReader(
            new FileInputStream(configureFile));
        BufferedReader bufferedReader = new BufferedReader(read);
        String line;
        while ((line = bufferedReader.readLine()) != null) {
          if (!selectedFields.contains(line)) {
            selectedFields.add(line);
          }
        }
        read.close();
      } else {
        log.error("Failed to find file:" + configureFile.getAbsolutePath());
      }
    } catch (Exception e) {
      log.error("Failed to read file:" + configureFile.getAbsolutePath(), e);
    }
  }
}