以编程方式配置DropWizard

时间:2015-08-04 10:20:46

标签: java configuration dropwizard metric codahale-metrics

我基本上有同样的问题as here,但我希望得到一个不太模糊,信息量更大的答案。

我正在寻找一种以编程方式配置DropWizard的方法,或者至少可以在运行时调整配置。具体来说,我有一个用例,我希望YAML文件中的configure metrics以2分钟的频率发布。这将是“正常”默认值。但是,在某些情况下,我可能希望将速度提高到每10秒一次,然后将其调整回正常/默认值。

我该如何做,而不仅仅是metrics.frequency属性,而是YAML配置文件中可能存在的任何配置?

3 个答案:

答案 0 :(得分:1)

Dropwizard读取YAML配置文件,并在启动时仅配置一次所有组件。 YAML文件和@transaction.commit_manually def my_view(request): try: MyModel_one(...).save(using='default') MyModel_two(...).save(using='db_one') MyModel_three(...).save(using='db_two') # <-- for example we make exception here (duplicate data) except IntegrityError: transaction.rollback() transaction.rollback(using='db_one') transaction.rollback(using='db_two') return ... transaction.commit() transaction.commit(using='db_one') transaction.commit(using='db_two') return ... 对象都不再使用。这意味着没有直接的方法来配置运行时。

它也没有提供可以操作组件的特殊接口/委托。但是,您可以访问组件的对象(通常;如果不是,您可以始终发送拉取请求)并根据需要手动配置它们。您可能需要稍微阅读一下源代码,但它通常很容易导航。

对于Configuration,您可以看到MetricsFactory类使用metrics.frequency设置为每个指标类型创建ScheduledReporterManager个对象,并且看起来不像在运行时更改它们。但是你可以以某种方式解决它,甚至更好,修改代码并向dropwizard社区发送一个Pull Request。

答案 1 :(得分:0)

尽管dropwizard不立即支持此功能,但是您可以使用它们提供的工具轻松地完成此操作。请注意,以下解决方案绝对适用于您提供的配置值,但可能不适用于内置配置值。

还请注意,这不会持久更新到config.yml的配置值。但是,这很容易实现,只需通过从应用程序写入配置文件即可实现自己。如果有人想编写此实现,请随时在下面链接的示例项目上open a PR

代码

以最小的配置开始:

config.yml

myConfigValue: "hello"

对应的configuration文件:

ExampleConfiguration.java

public class ExampleConfiguration extends Configuration {
    private String myConfigValue;

    public String getMyConfigValue() {
        return myConfigValue;
    }

    public void setMyConfigValue(String value) {
        myConfigValue = value;
    }
}

然后创建一个task来更新配置:

UpdateConfigTask.java

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,它允许您获取配置值:

ConfigResource.java

@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

ExampleApplication.java(摘要)

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.javaUpdateConfigTask.java的构造函数即可。如果您不熟悉此概念,请参见此处: Is Java "pass-by-reference" or "pass-by-value"?

上面的链接类指向我创建的项目,该项目将其作为完整的解决方案进行演示。这是项目的链接:

scottg489/dropwizard-runtime-config-example

脚注:我尚未验证built in configuration可以使用此功能。但是,您需要针对自己的配置扩展的dropwizard Configuration类确实具有用于内部配置的各种“设置程序”,但是更新run()之外的那些可能并不安全。



免责声明:我在这里链接的项目是我创建的。

答案 2 :(得分:0)

我通过 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();
}