spring cloud 在初次使用 hystrix dashboard仪表盘的时候很容易出现hystrix dashboard Unable to connect to Command Metric Stream错误
如下图:
首先查看依赖时候添加全
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
其次启动程序注解是否添加
@EnableCircuitBreaker
@EnableHystrixDashboard
如果都没问题那么检查下springboot 版本如果是2.0则需要添加 ServletRegistrationBean 因为springboot的默认路径不是 "/hystrix.stream",只要在自己的项目里配置上下面的servlet就可以了
@Bean public ServletRegistrationBean getServlet() { HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet(); ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet); registrationBean.setLoadOnStartup(1); registrationBean.addUrlMappings("/hystrix.stream"); registrationBean.setName("HystrixMetricsStreamServlet"); return registrationBean; }
修改完成重启服务问题便会解决
分析:
首先,查看源码中 类 HystrixStreamEndpoint 从中可以看到 new EndpointServlet(HystrixMetricsStreamServlet.class)
package org.springframework.cloud.netflix.hystrix;
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet; import java.util.Map; import java.util.function.Supplier; import org.springframework.boot.actuate.endpoint.web.EndpointServlet; import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpoint; @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; } public EndpointServlet get() { return (new EndpointServlet(HystrixMetricsStreamServlet.class)).withInitParameters(this.initParameters); } }
然后,我们再查看 HystrixMetricsStreamServlet 这个类 在方法的注释中我们可以看到
有提示 “Adding the following to web.xml”
而在springboot中是采用bean的形式配置就可以解决问题了
package com.netflix.hystrix.contrib.metrics.eventstream; import com.netflix.config.DynamicIntProperty; import com.netflix.config.DynamicPropertyFactory; import com.netflix.hystrix.contrib.sample.stream.HystrixSampleSseServlet; import com.netflix.hystrix.metric.consumer.HystrixDashboardStream; import com.netflix.hystrix.serial.SerialHystrixDashboardData; import rx.Observable; import rx.functions.Func1; import java.util.concurrent.atomic.AtomicInteger; /** * Streams Hystrix metrics in text/event-stream format. * <p> * Install by: * <p> * 1) Including hystrix-metrics-event-stream-*.jar in your classpath. * <p> * 2) Adding the following to web.xml: * <pre>{@code * <servlet> * <description></description> * <display-name>HystrixMetricsStreamServlet</display-name> * <servlet-name>HystrixMetricsStreamServlet</servlet-name> * <servlet-class>com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet</servlet-class> * </servlet> * <servlet-mapping> * <servlet-name>HystrixMetricsStreamServlet</servlet-name> * <url-pattern>/hystrix.stream</url-pattern> * </servlet-mapping> * } </pre> */ public class HystrixMetricsStreamServlet extends HystrixSampleSseServlet { private static final long serialVersionUID = -7548505095303313237L; /* used to track number of connections and throttle */ private static AtomicInteger concurrentConnections = new AtomicInteger(0); private static DynamicIntProperty maxConcurrentConnections = DynamicPropertyFactory.getInstance().getIntProperty("hystrix.config.stream.maxConcurrentConnections", 5); public HystrixMetricsStreamServlet() { this(HystrixDashboardStream.getInstance().observe(), DEFAULT_PAUSE_POLLER_THREAD_DELAY_IN_MS); } /* package-private */ HystrixMetricsStreamServlet(Observable<HystrixDashboardStream.DashboardData> sampleStream, int pausePollerThreadDelayInMs) { super(sampleStream.concatMap(new Func1<HystrixDashboardStream.DashboardData, Observable<String>>() { @Override public Observable<String> call(HystrixDashboardStream.DashboardData dashboardData) { return Observable.from(SerialHystrixDashboardData.toMultipleJsonStrings(dashboardData)); } }), pausePollerThreadDelayInMs); } @Override protected int getMaxNumberConcurrentConnectionsAllowed() { return maxConcurrentConnections.get(); } @Override protected int getNumberCurrentConnections() { return concurrentConnections.get(); } @Override protected int incrementAndGetCurrentConcurrentConnections() { return concurrentConnections.incrementAndGet(); } @Override protected void decrementCurrentConcurrentConnections() { concurrentConnections.decrementAndGet(); } }