以编程方式配置 DropWizard
Configuring DropWizard Programmatically
我有基本相同的问题as here,但我希望得到一个不那么含糊、信息更丰富的答案。
我正在寻找一种以编程方式配置 DropWizard 的方法,或者至少能够在运行时调整配置。具体来说,我有一个用例,我想 configure metrics 在 YAML 文件中以 2 分钟的频率发布。这将是 "normal" 默认值。但是,在某些情况下,我可能想加快速度,比如说,每 10 秒一次,然后将其限制回 normal/default.
我该怎么做,不仅针对 metrics.frequency
属性,还针对 YAML 配置文件中可能存在的任何配置?
Dropwizard 读取 YAML 配置文件并在启动时仅配置一次所有组件。 YAML 文件和 Configuration
对象都不再使用。这意味着没有直接的方法来配置 运行-time.
它也不提供特殊的 interfaces/delegates 您可以在其中操作组件。但是,您可以访问组件的对象(通常;如果不是,您可以随时发送拉取请求)并根据需要手动配置它们。您可能需要稍微阅读源代码,但通常很容易浏览。
在 metrics.frequency
的情况下,您可以使用 frequency
设置看到每个指标类型有 MetricsFactory class creates ScheduledReporterManager 个对象,并且看起来您无法在 [=21= 上更改它们]时间。但是您可能可以以某种方式或什至更好地解决它,修改代码并向 dropwizard 社区发送合并请求。
尽管 dropwizard 不立即支持此功能,但您可以使用他们为您提供的工具相当轻松地完成此操作。请注意,以下解决方案绝对适用于您提供的配置值,但它可能不适用于内置配置值。
另请注意,此 不会将更新后的配置值 保存到 config.yml
。但是,这很容易实现,只需从应用程序写入配置文件即可实现。如果有人想编写此实现,请随时 open a PR 我在下面 link 编辑的示例项目。
代码
从最小配置开始:
myConfigValue: "hello"
对应的configuration文件:
public class ExampleConfiguration extends Configuration {
private String myConfigValue;
public String getMyConfigValue() {
return myConfigValue;
}
public void setMyConfigValue(String value) {
myConfigValue = value;
}
}
然后创建一个 task 来更新配置:
public class UpdateConfigTask extends Task {
ExampleConfiguration config;
public UpdateConfigTask(ExampleConfiguration config) {
super("updateconfig");
this.config = config;
}
@Override
public void execute(Map<String, List<String>> parameters, PrintWriter output) {
config.setMyConfigValue("goodbye");
}
}
同样出于演示目的,创建一个 resource 允许您获取配置值:
@Path("/config")
public class ConfigResource {
private final ExampleConfiguration config;
public ConfigResource(ExampleConfiguration config) {
this.config = config;
}
@GET
public Response handleGet() {
return Response.ok().entity(config.getMyConfigValue()).build();
}
}
最后在你的 application:
中连接所有内容
environment.jersey().register(new ConfigResource(configuration));
environment.admin().addTask(new UpdateConfigTask(configuration));
用法
Start up the application 然后 运行:
$ curl 'http://localhost:8080/config'
hello
$ curl -X POST 'http://localhost:8081/tasks/updateconfig'
$ curl 'http://localhost:8080/config'
goodbye
工作原理
这只需将相同的引用传递给 ConfigResource.java
和 UpdateConfigTask.java
的构造函数即可。如果您不熟悉这个概念,请参阅此处:
Is Java "pass-by-reference" or "pass-by-value"?
上面的 linked classes 是我创建的一个项目,它演示了这是一个完整的解决方案。这是项目的 link:
scottg489/dropwizard-runtime-config-example
脚注:我还没有验证这是否适用于 built in configuration. However, the dropwizard Configuration class,您需要为自己的配置扩展它确实有各种用于内部配置的“setter”,但更新 run()
.
之外的内容可能不安全
免责声明:我在此处 link 编辑的项目是我创建的。
我通过 Javassist 通过字节码操作解决了这个问题
就我而言,我想改变“涌入”记者
并且 modifyInfluxDbReporterFactory 应该 运行 在 dropwizard 启动之前
private static void modifyInfluxDbReporterFactory() throws Exception {
ClassPool cp = ClassPool.getDefault();
CtClass cc = cp.get("com.izettle.metrics.dw.InfluxDbReporterFactory"); // do NOT use InfluxDbReporterFactory.class.getName() as this will force the class into the classloader
CtMethod m = cc.getDeclaredMethod("setTags");
m.insertAfter(
"if (tags.get(\"cloud\") != null) tags.put(\"cloud_host\", tags.get(\"cloud\") + \"_\" + host);tags.put(\"app\", \"sam\");");
cc.toClass();
}
我有基本相同的问题as here,但我希望得到一个不那么含糊、信息更丰富的答案。
我正在寻找一种以编程方式配置 DropWizard 的方法,或者至少能够在运行时调整配置。具体来说,我有一个用例,我想 configure metrics 在 YAML 文件中以 2 分钟的频率发布。这将是 "normal" 默认值。但是,在某些情况下,我可能想加快速度,比如说,每 10 秒一次,然后将其限制回 normal/default.
我该怎么做,不仅针对 metrics.frequency
属性,还针对 YAML 配置文件中可能存在的任何配置?
Dropwizard 读取 YAML 配置文件并在启动时仅配置一次所有组件。 YAML 文件和 Configuration
对象都不再使用。这意味着没有直接的方法来配置 运行-time.
它也不提供特殊的 interfaces/delegates 您可以在其中操作组件。但是,您可以访问组件的对象(通常;如果不是,您可以随时发送拉取请求)并根据需要手动配置它们。您可能需要稍微阅读源代码,但通常很容易浏览。
在 metrics.frequency
的情况下,您可以使用 frequency
设置看到每个指标类型有 MetricsFactory class creates ScheduledReporterManager 个对象,并且看起来您无法在 [=21= 上更改它们]时间。但是您可能可以以某种方式或什至更好地解决它,修改代码并向 dropwizard 社区发送合并请求。
尽管 dropwizard 不立即支持此功能,但您可以使用他们为您提供的工具相当轻松地完成此操作。请注意,以下解决方案绝对适用于您提供的配置值,但它可能不适用于内置配置值。
另请注意,此 不会将更新后的配置值 保存到 config.yml
。但是,这很容易实现,只需从应用程序写入配置文件即可实现。如果有人想编写此实现,请随时 open a PR 我在下面 link 编辑的示例项目。
代码
从最小配置开始:
myConfigValue: "hello"
对应的configuration文件:
public class ExampleConfiguration extends Configuration {
private String myConfigValue;
public String getMyConfigValue() {
return myConfigValue;
}
public void setMyConfigValue(String value) {
myConfigValue = value;
}
}
然后创建一个 task 来更新配置:
public class UpdateConfigTask extends Task {
ExampleConfiguration config;
public UpdateConfigTask(ExampleConfiguration config) {
super("updateconfig");
this.config = config;
}
@Override
public void execute(Map<String, List<String>> parameters, PrintWriter output) {
config.setMyConfigValue("goodbye");
}
}
同样出于演示目的,创建一个 resource 允许您获取配置值:
@Path("/config")
public class ConfigResource {
private final ExampleConfiguration config;
public ConfigResource(ExampleConfiguration config) {
this.config = config;
}
@GET
public Response handleGet() {
return Response.ok().entity(config.getMyConfigValue()).build();
}
}
最后在你的 application:
中连接所有内容environment.jersey().register(new ConfigResource(configuration));
environment.admin().addTask(new UpdateConfigTask(configuration));
用法
Start up the application 然后 运行:
$ curl 'http://localhost:8080/config'
hello
$ curl -X POST 'http://localhost:8081/tasks/updateconfig'
$ curl 'http://localhost:8080/config'
goodbye
工作原理
这只需将相同的引用传递给 ConfigResource.java
和 UpdateConfigTask.java
的构造函数即可。如果您不熟悉这个概念,请参阅此处:
Is Java "pass-by-reference" or "pass-by-value"?
上面的 linked classes 是我创建的一个项目,它演示了这是一个完整的解决方案。这是项目的 link:
scottg489/dropwizard-runtime-config-example
脚注:我还没有验证这是否适用于 built in configuration. However, the dropwizard Configuration class,您需要为自己的配置扩展它确实有各种用于内部配置的“setter”,但更新 run()
.
免责声明:我在此处 link 编辑的项目是我创建的。
我通过 Javassist 通过字节码操作解决了这个问题 就我而言,我想改变“涌入”记者 并且 modifyInfluxDbReporterFactory 应该 运行 在 dropwizard 启动之前
private static void modifyInfluxDbReporterFactory() throws Exception {
ClassPool cp = ClassPool.getDefault();
CtClass cc = cp.get("com.izettle.metrics.dw.InfluxDbReporterFactory"); // do NOT use InfluxDbReporterFactory.class.getName() as this will force the class into the classloader
CtMethod m = cc.getDeclaredMethod("setTags");
m.insertAfter(
"if (tags.get(\"cloud\") != null) tags.put(\"cloud_host\", tags.get(\"cloud\") + \"_\" + host);tags.put(\"app\", \"sam\");");
cc.toClass();
}