springcloud 使用admin監控中心某個服務一直處於下線狀態,但服務正常運行的解決方案

我在搭建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,還是對源碼不熟悉導致的!
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章