原因
在使用hystrix-dashboard面板的时候,然后我们然后显示错误“Unable to connect to Command Metric Stream”
分析
出现这个问题,首先我们需要检查一下,我们所依赖的jar是否有问题,需要依赖
其次是看启动项是否添加注解:@EnableHystrixDashboard,然后上网查了一下,
网上说
:
我们看到hytrix-dashboard上需要的接口是下面:
但是我们看到启动的console日志中打印出的是如下:
所以我们首先的解决方案,是把前面的”/application”去掉,需要在 .yml文件中配置上 ,然后上网查了一下,需要在 .yml文件中配置上
但是因为我用到的版本是“Greenwich.SR2”,是不支持的,所以这个方法也不能用了,然后终于在不懈努力下,然后解决方案;
解决方案
如果我们的SpringBoot是2.0以后版本,然后需要添加 ServletRegistrationBean 因为springboot的默认路径不是 “/hystrix.stream”。然后在项目中加上下面的配置就可以了;
@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();
}
}