2016-10-18 142 views
4

我有一个断路器设置,我想更改运行参数。客户现场需要调整线程和超时等事情。以编程方式更改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)); 

mycommand的实现标准HystrixCommand并调用超(hystrixProps)。

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

我不想通过属性文件或指定一个URL给Archaius。

也有答案告诉我要通过Archaius和ConfigurationManager.getConfigInstance()。setProperty(“...”)。但是肯定会有一种类似于我创建的原始制作者的方式?做它完全不同,因为这是第二次感到尴尬。

回答

1

为了将来的参考:我通过ConfigurationManager和一个字符串属性结束了使用设置。

ConfigurationManager.getConfigInstance().setProperty("...") 

它让我改变的东西,但在一个比原来的代码更少的类型安全的方式。我在字符串中拼写错了一段时间,这就是为什么我想避免这种错误的原因。

我现在用它来处理所有需要更改运行时的属性。每次改变一个新的Hystrix电路断路器(新的命令键)也是一种选择,但稍后会使用属性文件来破坏。

+0

我面临着类似的问题 - 一旦我在某个组中创建了第一个带有Setter的HystrixCommand,之后我无法通过创建一个具有不同Setter的新HystrixCommand来更改属性(在同一组中)。那么hystrix是如何从它获得的第一个Setter中“缓存”属性的情况的确如此,除了使用ConfigurationManager之外,真的没有办法改变属性吗? –

2

猬属性也可以在里面 @HystrixCommand注解我们的服务类设置,为此我们使用Hystrix-Javanica 项目,该项目用于我们的项目实施的注释。 为此,我们需要将hystrix-javanica的依赖关系添加到我们的 类路径中。

依赖Maven的:

<dependency> 
    <groupId>com.netflix.hystrix</groupId> 
    <artifactId>hystrix-javanica</artifactId> 
    <version>x.y.z</version> 
</dependency> 

里面的@HystrixCommand注解我们可以用@HystrixProperty为椎设置的属性。

样品@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: 
    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文件的具体格式是

hystrix: 
    command: 
     findAllProducts: 
      execution: 
       isolation: 
        thread: 
         timeoutInMilliseconds: 1000 
      circuitBreaker: 
       requestVolumeThreshold: 20 
       errorThresholdPercentage: 50 
      metrics: 
       rollingStats: 
        timeInMilliseconds: 10000 
        numBuckets: 10 
    threadpool: 
     ProductService: 
      coreSize: 10 

有关豪猪,鸦胆子访问进一步信息here

+0

我需要在运行时以编程方式更改属性,所以您不是真正回答我的问题。 Javanica很好,但我们没有让人们通过文件改变params。理论上我可以从代码写入一个文件,但这比我现在要做的更麻烦和间接:ConfigurationManager.getConfigInstance()。setProperty(“...”)。我只想在第一次初始化之后使用强类型的API来更改属性,就像我在第一次做的那样。字符串和可能的拼写错误/误解只是阻碍。就像它在我切换到它时所做的那样... –

2

迟到的答案,但今天我挣扎着同样的事情,并找到了一种方法。

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

然而,使用自定义HystrixPropertiesStrategy作为Plugin可以覆盖缓存键(并因此迫使猬重新评估的二传手传递给新的命令情况下,因为高速缓存关键是新的,所以它认为它是一个新的命令)。

然后,该代码将类似于此:

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(完全关闭缓存),但你必须豪猪的开销不必重建HystrixCommandProperties每次调用命令时

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

相关问题