笔者在用SpringBoot 2.1.4.RELEASE + SpringCloud Greenwich.SR5
学习Hystrix时,在Hystrix Dashboard页面出现了一个常见错误:hystrix dashboard Unable to connect to Command Metric Stream,截图如下:
而我直接在浏览器中输入hystrix.stream
地址:http://localhost:20081/actuator/hystrix.stream 是能访问到接口内容的
首先审查了下,项目需要的security及hystrix相关依赖都已添加:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-securityartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-hystrixartifactId>
<version>2.2.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboardartifactId>
dependency>
一开始我以为是SpringBoot2.0以上版本出现的:url增加/actuator、需要配置Servlet映射问题(参见此博客)。
@Bean
public ServletRegistrationBean getServlet() {
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/actuator/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
但发现此配置没有用,依然会报错。思考到我之前就可以通过直接输入地址:http://localhost:20081/actuator/hystrix.stream 访问到接口内容,那应该不会是SpringBoot2.0的问题,换其他思路
回看到后台服务的日志信息,发现后台服务报错与上文博客中的情况不同,为Http 401错误,日志如下
2021-11-13 20:36:30.002 WARN 22544 --- [io-20081-exec-7] ashboardConfiguration$ProxyStreamServlet : Failed opening connection to http://localhost:20081/actuator/hystrix.stream : 401 : HTTP/1.1 401
2021-11-13 20:36:30.007 WARN 22544 --- [o-20081-exec-10] ashboardConfiguration$ProxyStreamServlet : Failed opening connection to http://localhost:20081/actuator/hystrix.stream : 401 : HTTP/1.1 401
2021-11-13 20:36:45.476 INFO 22544 --- [trap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver : Resolving eureka endpoints via configuration
HTTP 401错误是指用户权限认证出现问题。这提醒了我,本次实验项目pom中的Security模块是很早之前练习Eureka时就已经引入的包,当时还做了一些自定义配置。
会不会是当时的自定义配置影响了接口的调用?查到相关代码如下:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
//所有的请求,都需要经过HTTP Basic认证
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic();
}
}
这里就看到了问题原因所在:Security设置的项目接口都需要HTTPBasic输入用户名和密码进行登录认证。但Dashboard页面框架是作为get参数来加载hystrix.stream后台接口,此时后台系统无法认证相关接口用户登录态问题,则报错401
因为需要Dashboard自己轮询http://localhost:20081/actuator/hystrix.stream 这个接口,所以需要让后台服务将此接口进行登录态放行,修改此方法:
@Override
protected void configure(HttpSecurity http) throws Exception {
//所有的请求,都需要经过HTTP Basic认证
http.authorizeRequests()
.antMatchers("/actuator/hystrix.stream").permitAll() //放行/actuator/hystrix.stream
.anyRequest().authenticated()
.and()
.httpBasic();
}
只增加了一行代码.antMatchers("/actuator/hystrix.stream").permitAll()
。完成后重启,发现Dashboard成功出现监控数据
遇到问题需要对症下药,查到原因才能更好的解决
最开始测试时,我在打开浏览器访问本项目其他接口时,也做过用户认证,cookie中记下了我的登录态。因此后来直接用浏览器打开http://localhost:20081/actuator/hystrix.stream 接口时没有弹出登录接口,以至于疏忽了Security安全认证的配置