我将 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 易于使用。提供一个单行的静态 block 就足够了
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 Boot Actuator。添加依赖后
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
hystrix-servo-metrics-publisher 不再工作了。包
com.netlix.servo
在 JMX MBean/属性中不可用。这是 小 具有禁用 spring-boot-starter-actuator 依赖项的示例项目:
hystrix-servo-metrics-publisher-jmx-example
如果启用了依赖项,则 hystrix-servo-metrics-publisher 不再起作用。
最佳答案
更新 :
我注意到您在示例项目中使用的是 Spring Boot 1.4.3,并且您的项目设置不正确。 Spring Boot 2.0.x 的情况有所不同,见下文。
您的示例项目设置问题
您正在使用 hystrix-servo-metrics-publisher
版本 1.5.9
.此版本与 Hystrix 版本不兼容 1.5.3
Spring Cloud 使用 Brixton.SR5
.您可以通过启动您的应用程序来观察不兼容性,调用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 解决方案
使用 Actuator 不再显示 JMX 指标的原因是由 ServoMetricsAutoConfiguration
引起的。 ,如果使用 Spring Boot Actuator 则激活。这里暴露了一个监视器注册 bean,它的配置依赖于 SpringMetricsConfigBean
.新的默认注册表类是 BasicMonitorRegistry
.
要恢复原来的默认 JMX 监视器注册表,添加 resources/application.properties
与行 netflix.metrics.servo.registryClass=com.netflix.servo.jmx.JmxMonitorRegistry
.
通过这种方式,指标通过 JMX 和 Spring Actuator 指标端点公开。
Spring Boot 2.0.x 解决方案
对于 Spring Boot 2,问题是不同的。我将问题追溯到 io.micrometer.core.instrument.binder.hystrix.HystrixMetricsBinder
( micrometer
是 spring-boot-actuator-autoconfigure
的依赖项)。在这里,任何现有的发布者都被替换为 MicrometerMetricsPublisher
当MetricsAutoConfiguration
类被触发。因此,声明 HystrixPlugins.getInstance().registerMetricsPublisher(HystrixServoMetricsPublisher.getInstance());
没有达到预期的效果。发布者被简单地丢弃了......
Hystrix 插件的问题是每个插件类型一次只能注册一个插件。因此,一种解决方案是用“元”插件替换现有插件,该插件委托(delegate)给多个插件实例。 HystrixSecurityAutoConfiguration
中也使用了这种方法.通过下面的配置类,我设法通过 JMX 和 Spring Boot Actuator(例如/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);
}
}
}
关于spring-boot-starter-actuator 与 hystrix-servo-metrics-publisher 冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42509711/