高可用條件之一是能夠 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"));
}
參考資料:
沒有留言:
張貼留言