봄 클라우드 설정 터 : 설정 - 서버 상태 점검 서버와 클라이언트 측 서비스 시간 초과 문제가 차단으로 이어질 때문에

온라인 springcloud는 config 서버 롬의 자식이, 마이크로 서비스 클러스터를 끊고 천천히하는 문제.

입구 층에서 추적 로그를 증가 :

org.springframework.cloud.config.server.environment.EnvironmentController.java

    @RequestMapping ( "/{name}/{profiles}/{label:.*}" )
     공공 환경 라벨 (@PathVariable 문자열 이름, @PathVariable 문자열 프로파일, 
            @PathVariable 문자열 라벨) { 
        경우 (이름! = null의 && 이름입니다. 포함 ( "(_)" )) {
             // "(_)"는 자식의 repo 이름 드문이지만, "/"일치시킬 수없는
             // 스프링 MVC에 의해 
            이름 = name.replace ( "(_)", " / " ); 
        } 
        경우 (라벨! = null의 && label.contains ( "(_)" )) {
             // "(_)"
            // 스프링 MVC의에 의해 
            라벨 = label.replace ( "(_)", "/" ); 
        } 
        스톱워치 SW = 새로운 스톱워치 ( "라벨" ); 
        sw.start (); 
        logger.info ( "EnvironmentController.labelled ()开始이름 = {} = {} 프로필, 라벨 {} =" 이름, 프로파일, 상표); 
        환경 환경 = .repository.findOne (이름, 프로필, 라벨); 
        sw.stop (); 
        logger.info ( "EnvironmentController.labelled ()结束이름 = {} = {} 프로필, 라벨 = {} = {耗时毫秒}, {} =耗时秒" 이름, 프로파일, 라벨, SW. getTotalTimeMillis () sw.getTotalTimeSeconds ());
        환경; 
    }

건강 검사는 로그 항목을 증가 ConfigServerHealthIndicator.java :

@Override
     보호  공극 doHealthCheck (Health.Builder 빌더) 발생 예외 { 
        스톱워치 SW = 새로운 스톱워치 ( "doHealthCheck을" ); 
        sw.start (); 
        logger.info ( "ConfigServerHealthIndicator.doHealthCheck ()开始빌더 = {}" , 작성기); 
        builder.up (); 
        목록 <지도 <문자열, 객체 >> 자세한 내용은 = 새로운 ArrayList를 <> ();
        대한 (문자열 이름 : .repositories.keySet ()) { 
            저장소 리포지토리 = .repositories.get (이름);
            문자열 응용 프로그램 = (repository.getName () == null이 )? 이름 : repository.getName (); 
            문자열 정보 = repository.getProfiles (); 

            시도 { 
                환경 환경 = .environmentRepository.findOne (응용 프로그램, 프로필, repository.getLabel ()); 

                의 HashMap <문자열, 개체> 세부 = 새로운 HashMap의 <> (); 
                detail.put ( "이름" , environment.getName ()); 
                detail.put ( "라벨" , environment.getLabel ());
                만약 (environment.getProfiles ()! = null이. && environment.getProfiles ()의 길이는> 0 ) { 
                    detail.put ( "프로파일" , Arrays.asList (environment.getProfiles ())); 
                } 

                경우 (! {CollectionUtils.isEmpty (environment.getPropertySources ())) 
                    목록 <문자열> 소스 = 새로운 ArrayList를 <> ();
                    (: environment.getPropertySources () PropertySource 소스) { 
                        sources.add (source.getName ()); 
                    } 
                    detail.put ( "소스" , 소스); 
                }
                details.add (세부 사항); 
            } 캐치 (예외 E) { 
                의 HashMap <문자열, 문자열>지도 =  의 HashMap <> (); 
                map.put ( "응용 프로그램" , 응용 프로그램); 
                map.put ( "프로파일" , 프로파일); 
                builder.withDetail ( "저장소" ,지도); 
                builder.down (E); 
                반환 ; 
            } 
        } 
        builder.withDetail ( "저장소" , 세부 사항); 
        sw.stop (); 
        logger.info ("ConfigServerHealthIndicator.doHealthCheck ()结束,耗时= {}毫秒,耗时= {}秒빌더 = {}" , sw.getTotalTimeMillis () sw.getTotalTimeSeconds (), 빌더); 
    }

로그의 시간이 소요되는 통계 분석 후와 EnvironmentController 및 ConfigServerHealthIndicator 호출 너무 많은 시간이 모두 호출 결국 () 메소드 JGitEnvironmentRepository.fetch를 호출 발견,이 방법은 요청 자식을 가져 갈 것입니다, 제한 시간은 약 5 초입니다.

때문에 요청의 과도한 번호, 서비스 요청은, 그러나, 스레드가 오랜 시간 동안 차단됩니다.

분석 :

1, 각 마이크로 시작한 서비스 모듈, 그리고 왜 EnvironmentController 전화를?

2, 확인하는 간격을 설정하여 문제를 완화 할 수 ConfigServerHealthIndicator는 설정 - 서버 상태 확인입니다 호출합니다.

    영사 : 
      호스트 : 10.200.110.100 
      포트 : 8500 
      활성화 : 사실 
      발견 : 
        활성화 : 사실 
        호스트 이름 : 10.200.110.100 
        healthCheckInterval : 30 대 
        queryPassing을 : 사실

 

때 클라이언트 측 설정 서버 시작 통화에 대한 건강 체크와 EnvironmentController 요청. 원본을 봐 :

레지스트리에 각 클라이언트 연결이 구성 예의 중심에 도착 후에는 논리 위의 코드는 환경 변수의 온라인 환경에 데이터 센터에서 얻도록 구성 호출, 문제가 발생하여 로그를 확인하고이 논리가 유지되는 것을 발견 건강 지표를 통해 구성 서버가 SpringCloudConfig에게 공식 문서를보고 구성 EnvironmentRepository가 제대로 작동 감지 여부를 알고, 응용 프로그램에 대한 응용 프로그램의 이름, 20 초마다 한 번 호출됩니다 호출합니다. 기본적으로 응용 프로그램이 EnvironmentRepository을 구성하는 응용 프로그램의 이름을 묻습니다, EnvironmentRepository 예는 기본 구성을 응답했습니다. 즉, 상태 모니터는 기본적으로 설정하는 경우, findOne 예외가있을 것입니다 여부를 구성, 사용할 수 있습니다 감지 호출 멈추지 않을 것입니다,

이 코드는 org.springframework.cloud.config.server.config.ConfigServerHealthIndicator 클래스의 초기화이다 응용 프로그램의 응용 프로그램 코드의 이름을 이름

@ConfigurationProperties ( "spring.cloud.config.server.health" )
 공개  수업 ConfigServerHealthIndicator는 확장 AbstractHealthIndicator { 

    개인 EnvironmentRepository environmentRepository을; 

    개인 지도 <문자열, 저장소> 저장소 =  의 LinkedHashMap <> (); 

    공개 ConfigServerHealthIndicator (EnvironmentRepository environmentRepository) {
          .environmentRepository = environmentRepository; 
    } 

    @PostConstruct 
    공공  무효 {) 초기화를 (
         경우 ( .repositories.isEmpty ()) {
              .repositories.put ( "응용 프로그램", 새로운 저장소 ()); 
        } 
    } 
       // ... 
}

당신이 spring.cloud.config.server.health.enabled 등의 검출을 중지하려면 = 거짓이 기능을 해제하도록 구성 할 수 있습니다.

원본을 봐 :. org.springframework.cloud.config.client ConfigClientAutoConfiguration.java

@Configuration
 공용  클래스 ConfigClientAutoConfiguration { 
    @Configuration 
    @ConditionalOnClass (HealthIndicator. 등급 ) 
    @ConditionalOnBean (ConfigServicePropertySourceLocator. 등급 )
     @ConditionalOnProperty (값 = "health.config.enabled"matchIfMissing = TRUE)을
     보호  정적  클래스 ConfigServerHealthIndicatorConfiguration { 

        @Bean 
        공개 ConfigServerHealthIndicator configServerHealthIndicator을 ( 
                ConfigServicePropertySourceLocator 로케이터, 
                ConfigClientHealthProperties 특성, 환경 환경) {
            반환  새로운 ConfigServerHealthIndicator (로케이터, 환경, 속성); 
        } 
    } 
// ...

 

추천

출처www.cnblogs.com/duanxz/p/11272215.html