本文主要研究一下spring cloud的HystrixAutoConfigurationhtml
spring-cloud-netflix-core-2.0.0.RELEASE-sources.jar!/org/springframework/cloud/netflix/hystrix/HystrixAutoConfiguration.javajava
/** * Auto configuration for Hystrix. * * @author Christian Dupuis * @author Dave Syer */ @Configuration @ConditionalOnClass({ Hystrix.class, HealthIndicator.class }) @AutoConfigureAfter({ HealthIndicatorAutoConfiguration.class }) public class HystrixAutoConfiguration { @Bean @ConditionalOnEnabledHealthIndicator("hystrix") public HystrixHealthIndicator hystrixHealthIndicator() { return new HystrixHealthIndicator(); } @Bean @ConditionalOnProperty(value = "management.metrics.hystrix.enabled", matchIfMissing = true) public HystrixMetricsBinder hystrixMetricsBinder() { return new HystrixMetricsBinder(); } /** * See original {@link org.springframework.boot.actuate.autoconfigure.jolokia.JolokiaEndpointAutoConfiguration} */ @Configuration @ConditionalOnWebApplication(type = SERVLET) @ConditionalOnBean(HystrixCommandAspect.class) // only install the stream if enabled @ConditionalOnClass({ HystrixMetricsStreamServlet.class }) @EnableConfigurationProperties(HystrixProperties.class) protected static class HystrixServletAutoConfiguration { @Bean @ConditionalOnEnabledEndpoint public HystrixStreamEndpoint hystrixStreamEndpoint(HystrixProperties properties) { return new HystrixStreamEndpoint(properties.getConfig()); } @Bean public HasFeatures hystrixStreamFeature() { return HasFeatures.namedFeature("Hystrix Stream Servlet", HystrixMetricsStreamServlet.class); } } @Configuration @ConditionalOnWebApplication(type = REACTIVE) @ConditionalOnBean(HystrixCommandAspect.class) // only install the stream if enabled @ConditionalOnClass({ DispatcherHandler.class }) @EnableConfigurationProperties(HystrixProperties.class) protected static class HystrixWebfluxManagementContextConfiguration { @Bean @ConditionalOnEnabledEndpoint public HystrixWebfluxEndpoint hystrixWebfluxController() { Observable<String> serializedDashboardData = HystrixDashboardStream.getInstance().observe() .concatMap(dashboardData -> Observable.from(SerialHystrixDashboardData.toMultipleJsonStrings(dashboardData))); Publisher<String> publisher = RxReactiveStreams.toPublisher(serializedDashboardData); return new HystrixWebfluxEndpoint(publisher); } @Bean public HasFeatures hystrixStreamFeature() { return HasFeatures.namedFeature("Hystrix Stream Webflux", HystrixWebfluxEndpoint.class); } } }
這裏有幾個bean,一個是HystrixHealthIndicator,還有HystrixMetricsBinder。另外關於endpoint,區分了servlet及webflux版本。
spring-cloud-netflix-core-2.0.0.RELEASE-sources.jar!/org/springframework/cloud/netflix/hystrix/HystrixHealthIndicator.javaweb
/** * A {@link HealthIndicator} implementation for Hystrix circuit breakers. * <p> * This default implementation will not change the system state (e.g. <code>OK</code>) but * includes all open circuits by name. * * @author Christian Dupuis */ public class HystrixHealthIndicator extends AbstractHealthIndicator { private static final Status CIRCUIT_OPEN = new Status("CIRCUIT_OPEN"); @Override protected void doHealthCheck(Builder builder) throws Exception { List<String> openCircuitBreakers = new ArrayList<>(); // Collect all open circuit breakers from Hystrix for (HystrixCommandMetrics metrics : HystrixCommandMetrics.getInstances()) { HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory .getInstance(metrics.getCommandKey()); if (circuitBreaker != null && circuitBreaker.isOpen()) { openCircuitBreakers.add(metrics.getCommandGroup().name() + "::" + metrics.getCommandKey().name()); } } // If there is at least one open circuit report OUT_OF_SERVICE adding the command // group // and key name if (!openCircuitBreakers.isEmpty()) { builder.status(CIRCUIT_OPEN).withDetail("openCircuitBreakers", openCircuitBreakers); } else { builder.up(); } } }
檢查斷路器的狀態
micrometer-core-1.0.5-sources.jar!/io/micrometer/core/instrument/binder/hystrix/HystrixMetricsBinder.javaspring
@NonNullApi @NonNullFields public class HystrixMetricsBinder implements MeterBinder { @Override public void bindTo(MeterRegistry registry) { // Keeps references of existing Hystrix plugins. HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance().getEventNotifier(); HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance().getPropertiesStrategy(); HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins.getInstance().getCommandExecutionHook(); HystrixConcurrencyStrategy concurrencyStrategy = HystrixPlugins.getInstance().getConcurrencyStrategy(); HystrixPlugins.reset(); // Registers existing plugins except the new MicroMeter Strategy plugin. HystrixPlugins.getInstance().registerMetricsPublisher(new MicrometerMetricsPublisher(registry)); HystrixPlugins.getInstance().registerConcurrencyStrategy(concurrencyStrategy); HystrixPlugins.getInstance().registerEventNotifier(eventNotifier); HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy); HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook); } }
這裏導出metrics到micrometer
spring-cloud-netflix-core-2.0.0.RELEASE-sources.jar!/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpoint.javaapp
/** * {@link org.springframework.boot.actuate.endpoint.annotation.Endpoint} to expose a Jolokia {@link HystrixMetricsStreamServlet}. * * @author Phillip Webb * @since 2.0.0 */ @ServletEndpoint(id = "hystrix.stream") public class HystrixStreamEndpoint implements Supplier<EndpointServlet> { private final Map<String, String> initParameters; public HystrixStreamEndpoint(Map<String, String> initParameters) { this.initParameters = initParameters; } @Override public EndpointServlet get() { return new EndpointServlet(HystrixMetricsStreamServlet.class) .withInitParameters(this.initParameters); } }
這個是基於servlet的
spring-cloud-netflix-core-2.0.0.RELEASE-sources.jar!/org/springframework/cloud/netflix/hystrix/HystrixWebfluxEndpoint.javaide
@RestControllerEndpoint(id = "hystrix.stream") public class HystrixWebfluxEndpoint { private final Flux<String> stream; public HystrixWebfluxEndpoint(Publisher<String> dashboardData) { stream = Flux.interval(Duration.ofMillis(500)).map(aLong -> "{\"type\":\"ping\"}") .mergeWith(dashboardData).share(); } // path needs to be empty, so it registers correct as /actuator/hystrix.stream @GetMapping(path = "", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<String> hystrixStream() { return stream; } }
這個是基於webflux的
HystrixAutoConfiguration主要是配置了HystrixHealthIndicator、HystrixMetricsBinder以及HystrixEndpoint(分servlet與webflux版本
)。ui