我设置了断路器,我想更改运行时的参数。需要在客户现场调整线程和超时等内容。
我像这样创建一个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(“...”)来浏览Archaius。但肯定有一种类似于我创造的原始设定者的方式吗?这样做完全不同,因为这是第二次感觉很尴尬。
答案 0 :(得分:6)
迟到的答案,但今天我在同样的事情上挣扎并找到了办法。
实现默认属性管理器的方式是它根据您运行的命令的名称使用HystrixCommandProperties
的缓存。在第一次使用该命令时,它会缓存从传递给Command的构造函数的HystrixCommandProperties.Setter
中得到的内容。
但是,使用自定义HystrixPropertiesStrategy
作为Plugin,您可以覆盖缓存键(因此强制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);
}
}
或者,你总是可以从null
方法返回getCommandPropertiesCacheKey
(完全关闭缓存),但是你有Hystrix每次重建HystrixCommandProperties
的开销。命令称为
PS:确保使用正确的线程同步来读取和更新这些属性,因为这些属性将从不同的线程调用。为简单起见,我在此示例中省略了,但实际上我在代码中使用ReentrantReadWriteLock
来保护对这些变量的访问
答案 1 :(得分:3)
供将来参考:我最终使用ConfigurationManager中的设置和字符串属性。
ConfigurationManager.getConfigInstance().setProperty("...")
它让我改变了一些东西,但是它的方式比原始代码更安全。我确实在弦乐器中输入了一段时间而斗争了,这就是为什么我要避免这种情况。
我现在将此用于我需要更改运行时的所有属性。每次更改时都会创建一个新的Hystrix断路器(新命令键)也可以作为选项,但稍后会使用属性文件中断。
答案 2 :(得分:2)
Hystrix属性也可以在我们的服务类里面设置 @HystrixCommand注释,为此我们使用Hystrix-Javanica 用于在我们的项目中实现注释的项目。 为此,我们需要将hystrix-javanica的依赖项添加到我们的 类路径。
对Maven的依赖:
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-javanica</artifactId>
<version>x.y.z</version>
</dependency>
在@HystrixCommand注释中,我们可以使用@HystrixProperty来设置hystrix的属性。
示例@HystrixCommand属性设置:
@HystrixCommand(groupKey = "StoreSubmission", commandKey = "StoreSubmission", threadPoolKey = "StoreSubmission", commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "30000"),
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "4"),
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "60000"),
@HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "180000") }, threadPoolProperties = {
@HystrixProperty(name = "coreSize", value = "30"),
@HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "180000") })
public String storeSubmission(ReturnType returnType, InputStream is, String id) {
}
定义这些属性的最佳方法是在外部化的 application.yaml 中,这样您就可以更好地控制它了。为不同的环境改变它们。
以下是我的application.yaml中的示例hystrix配置
hystrix:
command.StoreSubmission.execution.isolation.thread.timeoutInMilliseconds: 30000
command.StoreSubmission.circuitBreaker.requestVolumeThreshold: 4
command.StoreSubmission.circuitBreaker.sleepWindowInMilliseconds: 60000
command.StoreSubmission.metrics.rollingStats.timeInMilliseconds: 180000
collapser.StoreSubmission.maxRequestsInBatch: 1
collapser.StoreSubmission.requestCache.enabled: FALSE
threadpool.StoreSubmission.coreSize: 30
threadpool.StoreSubmission.metrics.rollingStats.timeInMilliseconds: 180000
application.yml文件的Exact格式为
hystrix:
command:
findAllProducts:
execution:
isolation:
thread:
timeoutInMilliseconds: 1000
circuitBreaker:
requestVolumeThreshold: 20
errorThresholdPercentage: 50
metrics:
rollingStats:
timeInMilliseconds: 10000
numBuckets: 10
threadpool:
ProductService:
coreSize: 10
有关Hystrix-Javanica的更多信息,请访问here
答案 3 :(得分:2)
有一种非常简单的方法可以做到这一点。它只需要两个步骤: 一个。注册正确的插件 湾使用所需的覆盖添加正确的策略。
用例:从1000毫秒覆盖ExecutionTimeoutInMilliseconds到30000毫秒
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);
}
});
这里我只是覆盖了必需的属性。运行应用程序时,您可以在DEBUG模式下看到:
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
答案 4 :(得分:0)
对于我HystrixPropertiesStrategy
和ConfigurationManager.getConfigInstance().setProperty(..)
并没有帮助,我最终创建了自己的HystrixDynamicProperty实现,如下所示,
public CustomHystrixDynamicProperty extends HystrixDynamicPropertiesArchaius {
@Override
public HystrixDynamicProperty<Integer> getInteger(final String name, final Integer fallback) {
if(name.equals("Your hystrix Property")){
return new HystrixDynamicProperty<Integer>() {
public Integer get() {
// Place your logic here...
return yourValue;
}
public String getName(){ return name;};
public void addCallback(Runnable callback) {};
}
} else {
return super.getInteger(name,fallback);
}
}
}
并在启动Spring Boot应用程序之前在“属性”下方添加。
System.setProperty("hystrix.plugin.HystrixDynamicProperties.implementation","YourPackage.CustomHystrixDynamicProperty");
对于好奇的开发人员 :: HystrixPropertiesChainedProperty中的getDynamicProperty方法通过 HystrixPropertiesStrategy 覆盖了覆盖的值,每次为“ HystrixPropertiesStrategy 设置“ HystrixCommand”之前都会被“ AbstractCommand”调用执行, 因此HystrixPropertiesStrategy的想法对我不起作用。