我在搭建springcloud时,使用了springcloud-admin监控中心,其他服务都正常,唯独后台管理服务一直处于下线状态,但服务是可以正常访问的。查询诸多原因后,这篇文章拯救了我:解决 Spring Cloud 的服务应用配置 context-path 后 Spring Boot Admin 监控不到信息的问题
正常情况下,访问服务+端口+/actuator/health就可以看到这个服务是否健康,前提是你服务中引入了这个包:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
第一个坑:context-path上下文
服务配置了 context-path 这个属性,导致 Spring Boot Admin 一直获取不到这个服务的端点信息(当时我对 Spring Boot Admin 的使用、原理还不熟悉),现在通过 Spring Boot Admin 的部分源码分析来看看怎么解决这个问题,记录一下我踩到的坑。
server:
tomcat:
uri-encoding: UTF-8
max-threads: 1000
min-spare-threads: 30
port: 8102
servlet:
context-path: /order-admin
解决方案:
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka/
# 如果项目配置有 server.servlet.context-path 属性,想要被 spring boot admin 监控,就要配置以下属性
instance:
metadata-map:
management:
context-path: /${server.servlet.context-path}/actuator
health-check-url: http://localhost:${server.port}/${server.servlet.context-path}/actuator/health
status-page-url: http://localhost:${server.port}/${server.servlet.context-path}/actuator/info
home-page-url: http://localhost:${server.port}/
然而,其中一个提供接口的服务通过以上配置解决了问题!
第二个坑:服务中整合了shiro
有一个服务是后台管理服务,这个服务整合了shiro,熟悉的人都知道,除了某些特别的请求,其他都会被重定向,我发现这个服务还是down,我就访问它的健康检查接口,发现自动跳转到了登录页,灵光一现,是不是要在shiro的配置文件中把健康检查的接口过滤呢,于是:
/**
* Shiro的配置文件
*
* @author KURO clarence_liang@163.com
*/
@Configuration
public class ShiroConfig {
/**
* 单机环境,session交给shiro管理
*/
@Bean
@ConditionalOnProperty(prefix = "xky", name = "cluster", havingValue = "false")
public DefaultWebSessionManager sessionManager(@Value("${xky.globalSessionTimeout:3600}") long globalSessionTimeout){
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setSessionValidationSchedulerEnabled(true);
sessionManager.setSessionIdUrlRewritingEnabled(false);
sessionManager.setSessionValidationInterval(globalSessionTimeout * 1000);
sessionManager.setGlobalSessionTimeout(globalSessionTimeout * 1000);
return sessionManager;
}
/**
* 集群环境,session交给spring-session管理
*/
@Bean
@ConditionalOnProperty(prefix = "xky", name = "cluster", havingValue = "true")
public ServletContainerSessionManager servletContainerSessionManager() {
return new ServletContainerSessionManager();
}
@Bean("securityManager")
public SecurityManager securityManager(UserRealm userRealm, SessionManager sessionManager) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm);
securityManager.setSessionManager(sessionManager);
securityManager.setRememberMeManager(null);
return securityManager;
}
@Bean("shiroFilter")
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
shiroFilter.setSecurityManager(securityManager);
shiroFilter.setLoginUrl("/login.html");
shiroFilter.setUnauthorizedUrl("/");
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/swagger/**", "anon");
filterMap.put("/v2/api-docs", "anon");
filterMap.put("/swagger-ui.html", "anon");
filterMap.put("/webjars/**", "anon");
filterMap.put("/swagger-resources/**", "anon");
filterMap.put("/statics/**", "anon");
filterMap.put("/login.html", "anon");
filterMap.put("/sys/login", "anon");
filterMap.put("/favicon.ico", "anon");
filterMap.put("/captcha.jpg", "anon");
// 过滤健康检查,否则监控中心无法上线
filterMap.put("/actuator/**", "anon");
filterMap.put("/**", "authc");
shiroFilter.setFilterChainDefinitionMap(filterMap);
return shiroFilter;
}
@Bean("lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
}
增加过滤后,解决问题!
总结:初学springcloud,还是对源码不熟悉导致的!