我有一个断路器设置,我想要更改运行时的参数。像线程和超时这样的东西需要在客户现场进行调整。
我创建一个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));
MyCommand实现标准HystrixCommand并调用super(hystrixProps)。
这在第一次是有效的,但是当我尝试在运行时更改属性(相同的组名)时,没有任何反应。有没有其他方法可以通过编程来改变这一点?
我不想遍历属性文件或指定Archaius的URL。
也有一些答案告诉我要通过ConfigurationManager.getConfigInstance().setProperty("...")了解阿查尤斯。但肯定会有一种类似于我创建的原始setter的方式?做这件事完全不同,因为这是第二次,感觉很尴尬。
发布于 2016-11-15 17:04:14
作为将来的参考:我最终通过ConfigurationManager和一个字符串属性使用了这些设置。
ConfigurationManager.getConfigInstance().setProperty("...")
它让我改变了一些东西,但是比起原来的代码,它的类型安全性更低。我确实为字符串中的一个打字错误挣扎了一段时间,这就是为什么我想要避免这种情况。
我现在将它用于更改运行时所需的所有属性。每次有变化时创建一个新的Hystrix断路器(新的命令键)也是一个选项,但稍后会使用属性文件中断。
发布于 2017-05-23 03:48:00
回答晚了,但今天我也遇到了同样的问题,并找到了一种方法。
默认属性管理器的实现方式是,它根据您运行的命令名使用HystrixCommandProperties
缓存。在第一次使用该命令时,它会缓存从传递给该命令的构造函数的HystrixCommandProperties.Setter
中获得的内容,仅此而已。
但是,使用自定义HystrixPropertiesStrategy
作为Plugin,您可以覆盖缓存键(因此强制Hystrix重新计算传递给新命令实例的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);
}
}
或者,您也可以始终从getCommandPropertiesCacheKey
方法返回null
(这将完全关闭缓存),但是这样就会产生Hystrix必须在每次调用命令时重新构建HystrixCommandProperties
的开销
PS:确保使用适当的线程同步来读取和更新这些属性,因为这些属性将从不同的线程调用。为简单起见,我在此示例中省略了这一点,但实际上我在代码中使用了ReentrantReadWriteLock
来保护对这些变量的访问
发布于 2018-06-09 06:35:05
有一种非常简单的方法可以做到这一点。它只需要两个步骤: a.注册正确的插件b.使用所需的覆盖添加正确的策略。
使用案例:将ExecutionTimeoutInMilliseconds从1000ms覆盖到30000 ms
HystrixPlugins.getInstance().registerPropertiesStrategy(new HystrixPropertiesStrategy() {
@Override
public HystrixCommandProperties getCommandProperties(HystrixCommandKey commandKey, HystrixCommandProperties.Setter builder) {
HystrixCommandProperties.Setter timeout
= HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(30000);
return super.getCommandProperties(commandKey, timeout);
}
});
在这里,我只是覆盖了所需的属性。当你运行你的应用程序时,你可以在调试模式下看到:
2018-06-08 23:18:32 [main] DEBUG c.n.h.s.p.HystrixPropertiesChainedProperty - Flipping property: hystrix.command.Client#getAllData().execution.isolation.thread.timeoutInMilliseconds to use its current value: 30000
https://stackoverflow.com/questions/40109374
复制相似问题