spring-boot-starter-actuator is in conflict with hystrix-ser



我使用spring-boot 1.4.3.Release与Netflix Hystrix使用,我将通过JMX提供HyStrix指标。HyStrix包含在此片段中的项目中

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>Brixton.SR5</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

对于通过JMX的指标,我使用HyStrix-Servo-Metrics-Publisher 1.5.9

<dependency>
  <groupId>com.netflix.hystrix</groupId>
  <artifactId>hystrix-servo-metrics-publisher</artifactId>
  <version>1.5.9</version>
</dependency>

HyStrix-Servo-Metrics-Publisher易于使用。足以提供一个单行的静态块 HystrixPlugins.getInstance().registerMetricsPublisher(HystrixServoMetricsPublisher.getInstance());如下所示

@EnableCircuitBreaker
@SpringBootApplication
public class ExampleApplication extends SpringBootServletInitializer {
  static {
    HystrixPlugins.getInstance().registerMetricsPublisher(HystrixServoMetricsPublisher.getInstance());
  }
  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    return application.sources(ExampleApplication.class);
  }
  public static void main(String[] args) {
    SpringApplication.run(ExampleApplication.class, args);
}
} 

它工作得很好。

,但我们也需要我们的项目弹簧启动执行器。添加依赖项

之后
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

HyStrix-Servo-Metrics-Publisher不再起作用。JMX MBEANS/属性不可用该软件包com.netlix.servo

这是小型带有禁用的弹簧启动 - 启动器依赖性的示例项目:Hystrix-Servo-Metrics-Publisher-JMX-example

如果依赖性启用了HyStrix-Servo-Metrics-Publisher不再起作用。

update :我注意到您在示例项目中使用了Spring Boot 1.4.3,并且您的项目设置不正确。Spring Boot 2.0.x的情况有所不同,请参见下文。

您的示例项目设置问题

您正在使用hystrix-servo-metrics-publisher版本1.5.9。此版本与Spring Cloud Brixton.SR5使用的HyStrix版本1.5.3不兼容。您可以通过启动应用程序,调用http://localhost:8080/remotecall(创建初始HyStrix指标),然后访问http://localhost:8080/metrics(访问执行器端点)来观察不兼容。然后您得到java.lang.NoSuchMethodError: com.netflix.hystrix.HystrixThreadPoolProperties.maximumSize()Lcom/netflix/hystrix/strategy/properties/HystrixProperty;。将版本设置为1.5.3解决此问题。

Spring Boot的解决方案1.x

执行器不再可见JMX指标的原因是ServoMetricsAutoConfiguration引起的,如果使用Spring Boot执行器,则会激活。在这里,显示了监视注册表bean,其配置取决于SpringMetricsConfigBean。新的默认注册表类是BasicMonitorRegistry

要返回原始默认JMX监视器注册表,请添加使用netflix.metrics.servo.registryClass=com.netflix.servo.jmx.JmxMonitorRegistryresources/application.properties。这样,通过JMX和弹簧执行器指标端点暴露了指标。

Spring Boot 2.0.x

的解决方案

对于Spring Boot 2,问题是不同的。我将问题跟踪到io.micrometer.core.instrument.binder.hystrix.HystrixMetricsBindermicrometerspring-boot-actuator-autoconfigure的依赖性)。在这里,当MetricsAutoConfiguration类触发时,任何现有的发布者都将被MicrometerMetricsPublisher替换。因此,语句HystrixPlugins.getInstance().registerMetricsPublisher(HystrixServoMetricsPublisher.getInstance());没有所需的效果。出版商只是丢弃...

HyStrix插件的问题是,每个插件类型一次只能注册一个插件。因此,解决方案是将现有插件替换为将"元"插件替换为将其委派给多个插件实例。HystrixSecurityAutoConfiguration也使用了此方法。在下面的配置类的情况下,我设法通过JMX和Spring Boot执行器(例如/actuator/Metrics/HyStrix.execution)获取HyStrix指标:

import com.netflix.hystrix.*;
import com.netflix.hystrix.contrib.servopublisher.HystrixServoMetricsPublisher;
import com.netflix.hystrix.strategy.HystrixPlugins;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier;
import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook;
import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher;
import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisherCollapser;
import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisherCommand;
import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisherThreadPool;
import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
@Configuration
@ConditionalOnClass({Hystrix.class, HystrixServoMetricsPublisher.class})
@AutoConfigureAfter(MetricsAutoConfiguration.class)
public class HystrixServoAndMicrometerConfig {
    @PostConstruct
    public void init() {
        // Keeps references of existing Hystrix plugins
        HystrixMetricsPublisher existingMetricsPublisher = HystrixPlugins.getInstance().getMetricsPublisher();
        HystrixConcurrencyStrategy concurrencyStrategy = HystrixPlugins.getInstance().getConcurrencyStrategy();
        HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance().getEventNotifier();
        HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance().getPropertiesStrategy();
        HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins.getInstance().getCommandExecutionHook();
        if (existingMetricsPublisher != null) {
            HystrixPlugins.reset();
            // Registers existing plugins except the new ServoAndExistingMetricsPublisher plugin
            HystrixPlugins.getInstance().registerMetricsPublisher(new ServoAndExistingMetricsPublisher(
                    existingMetricsPublisher, HystrixServoMetricsPublisher.getInstance()));
            HystrixPlugins.getInstance().registerConcurrencyStrategy(concurrencyStrategy);
            HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);
            HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);
            HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook);
        } else {
            HystrixPlugins.getInstance().registerMetricsPublisher(HystrixServoMetricsPublisher.getInstance());
        }
    }
    private static class ServoAndExistingMetricsPublisher extends HystrixMetricsPublisher {
        private static class ServoAndOtherMetricsPublisherCommand implements HystrixMetricsPublisherCommand {
            private final HystrixMetricsPublisherCommand servoMetricsPublisherCommand;
            private final HystrixMetricsPublisherCommand existingMetricsPublisherCommand;
            ServoAndOtherMetricsPublisherCommand(HystrixMetricsPublisherCommand servoMetricsPublisherCommand,
                                                 HystrixMetricsPublisherCommand existingMetricsPublisherCommand) {
                this.servoMetricsPublisherCommand = servoMetricsPublisherCommand;
                this.existingMetricsPublisherCommand = existingMetricsPublisherCommand;
            }
            @Override
            public void initialize() {
                servoMetricsPublisherCommand.initialize();
                existingMetricsPublisherCommand.initialize();
            }
        }
        private final HystrixMetricsPublisher existingMetricsPublisher;
        private final HystrixMetricsPublisher servoMetricsPublisher;
        ServoAndExistingMetricsPublisher(HystrixMetricsPublisher existingMetricsPublisher,
                                         HystrixMetricsPublisher servoMetricsPublisher) {
            this.existingMetricsPublisher = existingMetricsPublisher;
            this.servoMetricsPublisher = servoMetricsPublisher;
        }
        @Override
        public HystrixMetricsPublisherCommand getMetricsPublisherForCommand(HystrixCommandKey commandKey, HystrixCommandGroupKey commandGroupKey, HystrixCommandMetrics metrics, HystrixCircuitBreaker circuitBreaker, HystrixCommandProperties properties) {
            HystrixMetricsPublisherCommand servoMetricsPublisherCommand = servoMetricsPublisher.getMetricsPublisherForCommand(commandKey, commandGroupKey, metrics, circuitBreaker, properties);
            HystrixMetricsPublisherCommand existingMetricsPublisherCommand = existingMetricsPublisher.getMetricsPublisherForCommand(commandKey, commandGroupKey, metrics, circuitBreaker, properties);
            return new ServoAndOtherMetricsPublisherCommand(servoMetricsPublisherCommand, existingMetricsPublisherCommand);
        }
        @Override
        public HystrixMetricsPublisherThreadPool getMetricsPublisherForThreadPool(HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolMetrics metrics, HystrixThreadPoolProperties properties) {
            return servoMetricsPublisher.getMetricsPublisherForThreadPool(threadPoolKey, metrics, properties);
        }
        @Override
        public HystrixMetricsPublisherCollapser getMetricsPublisherForCollapser(HystrixCollapserKey collapserKey, HystrixCollapserMetrics metrics, HystrixCollapserProperties properties) {
            return servoMetricsPublisher.getMetricsPublisherForCollapser(collapserKey, metrics, properties);
        }
    }
}

最新更新