当前位置: 首页 > 知识库问答 >
问题:

Spring-引导-启动-执行器与Hystrix-伺服-度量-发布器冲突

金烨华
2023-03-14

我使用Spring-Boot1.4.3.与Netflix Hystrix一起发布,我将通过JMX提供Hystrix度量。Hystrix由此片段包含在project中

<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-s伺服-metrics-publisher1.5.9

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

Hystrix-sero-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);
}
} 

它工作得很漂亮。

但我们也需要在我们的项目Spring引导执行器。添加依赖项后

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

Hystrix-伺服度量发布器不再工作了。在JMX MBeans/Attributes上没有com.netlix.source包。

下面是一个具有禁用的Spring-Boot-Starter-Actutor依赖项的小示例项目:hystrix-souro-metrics-publisher-jmx-example

共有1个答案

孟豪
2023-03-14

更新:我注意到您在示例项目中使用的是Spring Boot1.4.3,而您的项目设置是不正确的。Spring Boot 2.0.x的情况有所不同,请参见下文。

示例项目设置的问题

您使用的是hystrix-sero-metrics-publisher版本1.5.9。此版本与Spring Cloudbrixton.sr5使用的Hystrix版本1.5.3不兼容。通过启动应用程序,调用http://localhost:8080/RemoteCall(创建初始Hystrix度量),然后调用http://localhost:8080/metrics(访问执行器endpoint),可以观察到不兼容性。然后得到一个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监视器注册表,请添加一个resources/application.properties,其行为netflix.metrics.servo.registryclass=com.netflix.servo.JMX.jmxMonitorRegistry。这样,通过JMX和Spring Actuctor metricsendpoint来公开度量。

Spring Boot 2.0.x解决方案

对于Spring Boot2,问题是不同的。我将问题追踪到io.micrometer.core.instrument.binder.hystrix.hystrixmetricsbinder(micrometerspring-boot-acture-autocigure的依赖项)。在这里,当触发MetricSautoConfiguration类时,任何现有的发布服务器都被MicroMeterMetricSpublisher替换。因此,HystrixPlugins.getInstance().RegisterMetricSpublisher(HystrixServometricSpublisher.getInstance());语句不具有所需的效果。发布者被简单地丢弃...

Hystrix插件的问题是每个插件类型一次只能注册一个插件。因此,一个解决方案是用委托给多个插件实例的“元”插件替换现有的插件。在HystrixSecurityAutoConfiguration中也使用了这种方法。使用下面的config类,我设法通过JMX和Spring Boot执行器(例如/acture/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);
        }
    }
}
 类似资料:
  • 从这份官方文件中,很难确定这两个模块之间有什么区别。 谁能提供一个官方和规范的答案来解释两者的区别吗?

  • 可以用与Spring-Boot1.5类似的方式获取hystrix度量信息? 在1.5度量endpoint中,我有如下内容: 但现在有了使用千分尺的执行器/度量endpoint,我找不到任何对术语“Hystrix”、“Netflix”等的引用。 有什么方法可以不像我以前那样使用hystrix.streamendpoint来获取这些信息?或者这应该是有效的,我做错了什么吗?

  • 我一直在阅读Spring引导执行器,我很难区分两个应用程序。属性设置 我想自定义执行器endpoint的访问规则。我可以使用属性控制所有执行器endpoint灵敏度。我的理解是,敏感endpoint将需要授权。我还可以通过属性更改endpoint的可访问性。 敏感度控制和安全启动之间有什么区别?

  • 我正在运行一个Spring Boot2应用程序,并添加了致动器Spring Boot starter依赖项。我启用了所有webendpoint,然后调用: http://localhost:8080/acture/metrics 结果是: 但我缺少所有的JVM统计数据和其他内置度量。我错过了什么?我读到的每一件事都说,这些度量标准应该在任何时候都可用。 谢谢你的提示。

  • Spring Boot执行器的两个版本(1.2.5和1.3.0)在HealthMvcEndpoint,isUnrestricted()方法(&&and)中的实现存在差异。我明白这是为了保留这些限制 http://docs.spring.io/spring-boot/docs/current-snapshot/reference/htmlsingle/#production-ready-health

  • 我有一个带有执行器和Hystrix的spring-boot-app。 Spring-boot-version:1.3.1.发行版 当我将添加到某些方法时,endpoint将显示来自Hystrix的所有度量: 问题: 如何从endpoint中完全排除hystrix-metrics? 更新1 我试图通过以下方法排除伺服测量和观众测量: 1) 但两者都没有达到预期的效果。