以编程方式更改Hystrix属性

And*_*s S 8 java circuit-breaker hystrix

我有一个断路器设置,我想改变运行时的参数.需要在客户站点调整线程和超时等内容.

我像这样创建一个HystrixCommandProperties.Setter:

HystrixCommandProperties.Setter hystrixProps = 
    HystrixCommandProperties.defaultSetter()
        .withCircuitBreakerSleepWindowInMilliseconds(myconf.sleepWindow);
HystrixThreadPoolProperties.Setter threadPoolSettings = 
    HystrixThreadPoolProperties.Setter()
        .withCoreSize(myconf.threadPoolSize);

new MyCommand(HystrixCommand.Setter.withGroupKey("mygroup")
    .andCommandPropertiesDefaults(hystrixProps)
    .andThreadPoolPropertiesDefaults(threadPoolSettings));
Run Code Online (Sandbox Code Playgroud)

MyCommand实现标准的HystrixCommand并调用super(hystrixProps).

这是第一次工作,但是当我尝试在运行时更改属性(相同的组名)时没有任何反应.还有另一种以编程方式更改此方法的方法吗?

我不想浏览属性文件或指定Archaius的URL.

还有答案告诉我使用ConfigurationManager.getConfigInstance().setProperty("...")来浏览Archaius.但肯定有一种类似于我创造的原始设定者的方式吗?这样做完全不同,因为这是第二次感觉很尴尬.

Mic*_*ska 9

迟到的答案,但今天我挣扎着同样的事情并找到了办法.

实现默认属性管理器的方式是它使用HystrixCommandProperties基于您运行的命令名称的缓存.在第一次使用该命令时,它会缓存HystrixCommandProperties.Setter传递给Command的构造函数的内容,就是这样.

但是,使用自定义HystrixPropertiesStrategy作为插件,您可以覆盖缓存键(因此强制Hystrix重新评估传递给新Command实例的Setter,因为缓存键是新的,因此它认为它是一个新命令).

然后代码看起来类似于:

public HystrixCommandFactory(....) {
    HystrixPlugins.getInstance().registerPropertiesStrategy(new HystrixPropertiesStrategyWithReloadableCache());
    updateHystrixSettings();        
}

//configurable attributes
private volatile int commandTimeoutMillis;
private volatile long lastSettingsUpdatedTimestamp;
private volatile HystrixCommand.Setter setterForNewCommands;

private void updateHystrixSettings() {
    lastSettingsUpdatedTimestamp = LocalDateTime.now().toDateTime().getMillis();
    HystrixCommandProperties.Setter propertiesSetter = HystrixCommandProperties.Setter()
        .withExecutionTimeoutInMilliseconds(commandTimeoutMillis)
        .withExecutionTimeoutEnabled(true);

    this.setterForNewCommands = HystrixCommand.Setter
        .withGroupKey(HystrixCommandGroupKey.Factory.asKey(GROUP_NAME))
        .andCommandPropertiesDefaults(propertiesSetter);

}

public void setCommandTimeoutMillis(int commandTimeoutMillis) {     
    this.commandTimeoutMillis = commandTimeoutMillis;
    updateHystrixSettings();        
}

private class HystrixPropertiesStrategyWithReloadableCache extends HystrixPropertiesStrategy {

    @Override
    public String getCommandPropertiesCacheKey(HystrixCommandKey commandKey, HystrixCommandProperties.Setter builder) {
        return String.format("%s-%d", commandKey.name(), lastSettingsUpdatedTimestamp);
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,你总是可以nullgetCommandPropertiesCacheKey方法返回(完全关闭缓存),但是你HystrixCommandProperties每次调用一个Command时都需要重建Hystrix的开销.

PS:确保使用正确的线程同步来读取和更新这些属性,因为这些属性将从不同的线程调用.为简单起见,我在此示例中省略了它,但实际上ReentrantReadWriteLock我在代码中使用了一个来保护对这些变量的访问


And*_*s S 7

供将来参考:我最终通过 ConfigurationManager 和字符串属性使用了这些设置。

ConfigurationManager.getConfigInstance().setProperty("...")
Run Code Online (Sandbox Code Playgroud)

它让我改变一些东西,但比原始代码的类型安全性更低。一段时间以来,我确实在字符串中遇到了拼写错误,这就是我想避免这种情况的原因。

我现在将它用于我需要更改运行时的所有属性。每次更改(新命令键)时创建一个新的 Hystrix 断路器也可能是一个选项,但稍后会使用属性文件中断。