如何在程式裡動態載入配置檔案
阿新 • • 發佈:2019-01-25
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); } } }