admin管理员组

文章数量:1568424

成功解决java.lang.IllegalStateException:Another strategy was already registered.

  • 项目场景:
  • 问题描述:
  • 原因分析:
  • 解决方案:
      • 参考文章

**

项目场景:

项目场景:微服务项目使用了熔断器Hystrix配置,在添加spring-boot-starter-actuator依赖之后报错。

问题描述:

异常关键内容描述:
Caused by: java.lang.IllegalStateException: Another strategy was already registered.

控制台打印异常如下:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hystrixConfig': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Another strategy was already registered.
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:160) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:415) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1786) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	......
Caused by: java.lang.IllegalStateException: Another strategy was already registered.
	at com.netflix.hystrix.strategy.HystrixPlugins.registerConcurrencyStrategy(HystrixPlugins.java:190) ~[hystrix-core-1.5.18.jar:1.5.18]
	at com.myproject.common.hystrix.hystrixConfig.init(hystrixConfig.java:46) ~[upp-common-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_171]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_171]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_171]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_171]

原因分析:

Caused by: java.lang.IllegalStateException: Another strategy was already registered.

提示:已经注册策略,不能重复注册。

分析项目:
原来项目在使用feign和Hystrix结合进行服务之间调用时,为保证将上游服务的的请求header传递到下游服务,自定义了hystrix执行的隔离策略。
项目中自定义了策略,继承了HystrixConcurrencyStrategy,重写wrapCallable方法。

关键代码:

/**
 *
 * @Description:    Hystrix实现ThreadLocal上下文的传递
 * @Author: Yanzh
 * @Date: Created in 2021/06/03 10:28
 * @Copyright: Copyright (c) 2021
 * @Version: V1.0
 * @Modified: Yanzh
 */
public class RequestContextHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {
    private final Collection<HystrixCallableWrapper> wrappers;

    public RequestContextHystrixConcurrencyStrategy(Collection<HystrixCallableWrapper> wrappers) {
        this.wrappers = wrappers;
    }
    @Override
    public <T> Callable<T> wrapCallable(Callable<T> callable) {
        return new CallableWrapperChain<T>(callable, wrappers.iterator()).wrapCallable();
    }

    private static class CallableWrapperChain<T> {
        private final Callable<T> callable;
        private final Iterator<HystrixCallableWrapper> wrappers;

        CallableWrapperChain(Callable<T> callable, Iterator<HystrixCallableWrapper> wrappers) {
            this.callable = callable;
            this.wrappers = wrappers;
        }

        Callable<T> wrapCallable() {
            Callable<T> delegate = callable;
            while (wrappers.hasNext()) {
                delegate = wrappers.next().wrap(delegate);
            }
            return delegate;
        }
    }
}
/**
 *
 * @Description:    Hystrix实现配置
 * @Author: Yanzh
 * @Date: Created in 2021/06/03 10:28
 * @Copyright: Copyright (c) 2021
 * @Version: V1.0
 * @Modified: Yanzh
 */
@Configuration
public class hystrixConfig {
@PostConstruct
    public void init() {
         HystrixPlugins.getInstance().registerConcurrencyStrategy(new RequestContextHystrixConcurrencyStrategy(wrappers));
   }
}

解决方案:

重置策略;先删除已经注册的策略,重新注册新的策略,如下:
/**
 *
 * @Description:    与 Hystrix 相关的公共配置
 * @Author: Yanzh
 * @Date: Created in 2021/06/03 10:28
 * @Copyright: Copyright (c) 2021
 * @Version: V1.0
 * @Modified: Yanzh
 */
@Configuration
public class HystrixConfiguration {

    @Autowired(required = false)
    private List<HystrixCallableWrapper> wrappers;

    @Bean
    public HystrixCallableWrapper requestAttributeAwareCallableWrapper() {
        return new RequestAttributeAwareCallableWrapper();
    }

    @PostConstruct
    public void init() {
        if (!Collections.isEmpty(wrappers)) {
            try {
                HystrixConcurrencyStrategy strategy = HystrixPlugins.getInstance().getConcurrencyStrategy();
                if (strategy instanceof RequestContextHystrixConcurrencyStrategy) {
                    return;
                }
                HystrixConcurrencyStrategy hystrixConcurrencyStrategy = new RequestContextHystrixConcurrencyStrategy(wrappers);
                // 获取原来的相关数据配置
                HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins.getInstance().getCommandExecutionHook();
                HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance().getEventNotifier();
                HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance().getMetricsPublisher();
                HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance().getPropertiesStrategy();
                logger.debug("Registering Muses Hystrix Concurrency Strategy.");

                // 重置再重新填充
                // 直接设置会触发异常 Caused by: java.lang.IllegalStateException: Another strategy was already registered.
                HystrixPlugins.reset();
                HystrixPlugins.getInstance().registerConcurrencyStrategy(hystrixConcurrencyStrategy);
                HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook);
                HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);
                HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher);
                HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);

            } catch (Exception e) {
                logger.error("Failed to register Muses Hystrix Concurrency Strategy", e);
            }
        }
    }
}

参考文章

https://blog.csdn/weihao_/article/details/83240099
https://shanhy.blog.csdn/article/details/108668952

本文标签: langJavaIllegalStateExceptionregisteredStrategy