高可用條件之一是能夠 hot reload (熱重載)。簡單的做法是每次使用的時候就是讀檔,使用 Properties 或是 snakeyaml。另一種方法是使用 commons-configuration2 套件提供的功能:
public static ReloadingFileBasedConfigurationBuilder<YAMLConfiguration> getBuilder(File file) { Parameters params = new Parameters(); ReloadingFileBasedConfigurationBuilder<YAMLConfiguration> builder = new ReloadingFileBasedConfigurationBuilder<>(YAMLConfiguration.class) .configure(params.fileBased().setFile(file)); // 每次讀取時檢查 builder.addEventListener(ConfigurationBuilderEvent.CONFIGURATION_REQUEST, event -> builder.getReloadingController().checkForReloading(null)); // 每分鐘檢查 PeriodicReloadingTrigger trigger = new PeriodicReloadingTrigger(builder.getReloadingController(), null, 1, TimeUnit.MINUTES); trigger.start(); return builder; } @Test public void testHotReload() throws Exception { File tmpFile = File.createTempFile("test", ".yml"); tmpFile.deleteOnExit(); String raw1 = "sample:\n property: test-1\n"; Files.write(tmpFile.toPath(), raw1.getBytes()); ImmutableConfiguration config1 = getBuilder(tmpFile).getConfiguration(); Assert.assertEquals("test before hot reload", "test-1", config1.getString("sample.property")); // NOTE. File#setLastModified() only guarantees that the file modification time is accurate to the second, so // the modification must be delayed by 1 second. Thread.sleep(1000); String raw2 = "sample:\n property: test-2\n"; Files.write(tmpFile.toPath(), raw2.getBytes()); ImmutableConfiguration config2 = getBuilder(tmpFile).getConfiguration(); Assert.assertEquals("test after hot reload", "test-2", config2.getString("sample.property")); }
參考資料: