Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Registering Hystrix Concurrency Strategy fails after migrating to spring-boot-2.0

Trying to register hystrix concurrency strategy fails after migrating to Spring-boot-2.0 with spring actuator enabled with java.lang.IllegalStateException stating that "Another strategy was already registered" . This is although I have not used registerConcurrencyStrategy anywhere else in my code.

I'd like to register concurrency strategy to carry-forward Log MDC context so that I'm able to log both within and outside the Hystrix wrapped method equally well, which includes thread-locals. And this used to work perfectly in spring-boot-1.5

After having migrated to spring-boot 2.0 (from 1.5), the HystrixPlugins.getInstance().registerConcurrencyStrategy(this); fails with IllegalStateException

As per https://github.com/Netflix/Hystrix/issues/1057, this issue can come if either (a) Any other code flow would have registered its own or default ConcurrencyStrategy before this is invoked (b) any call would have come via Hystrix before this is invoked

Since the above invocation is within the constructor of a class which is annotated with @Component, this should get invoked ideally before any method call happens (except initialization of other beans, including their constructors).

We even tried moving this code inside the SpringBoot Application Class's main method before invoking the SpringApplication.run(MyApplication.class, args); but that also didn't work

@Component
public class ContextCopyHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {

    private static final String EVENT = "HystrixConcurrencyStrategy";
    private static final String ACTION = "ContextCopy";

    public ContextCopyHystrixConcurrencyStrategy(Logger logger, LoggerUtil defaultLoggerUtil) {

        try {
            HystrixPlugins.getInstance().registerConcurrencyStrategy(this);
        } catch (IllegalStateException e) {
            defaultLoggerUtil.logEvents(logger, Level.WARN, e.getMessage(), EVENT, ACTION, "", "Race condition! Could not register strategy. HystrixConcurrencyStrategy is already initialized.");
        }

Expected: My registering should have happened before any other code and registering should have been successful

Actual: My registering fails with IllegalStateException

How do I make sure that my registering happens well before any other registering (which is not present in my code, but may be inside some of the libraries that I may be transitively using)

like image 887
Kundan Burnwal Avatar asked Nov 18 '25 09:11

Kundan Burnwal


2 Answers

By default, Spring boot 2 accuator registers Hystrix Metric Binder beans which reset already set HystrixConcurrencyStrategy and sets HystrixConcurrencyStrategyDefault. So, disabling that bean by

management.metrics.binders.hystrix.enabled=false

would help not resetting your custom HystrixConcurrencyStrategy

like image 162
arun Avatar answered Nov 20 '25 00:11

arun


We took a close look at my maven .m2 directory classes and looked for registerConcurrencyStrategy inside all the classes in all the jars. And we found that

io.micrometer.core.instrument.binder.hystrix

was internally registering the HystrixConcurrencyStrategy with the default one.

And upon further research we found that setting the following property in application.properties: management.metrics.binders.hystrix.enabled=false disabled the Hystrix Metrics Binder (I'm actually not sure what it does though!) and then things worked

like image 34
Kundan Burnwal Avatar answered Nov 20 '25 01:11

Kundan Burnwal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!