我在搭建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 [email protected]
*/
@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,還是對源碼不熟悉導致的!