ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Config Server Git 저장소 설정파일 수정할때마다 Config Client에게 전달하기 / Dynamic Configuration
    웹개발/Micro Service Architecture 2019. 4. 18. 11:48

    환경

    Config Server

    'org.springframework.cloud:spring-cloud-config-server'

    org.springframework.cloud:spring-cloud-config-monitor'

    'org.springframework.cloud:spring-cloud-starter-stream-rabbit'

     

    Config Client

    'org.springframework.cloud:spring-cloud-config-client'

    'org.springframework.cloud:spring-cloud-starter-bus-amqp'

     

    이렇게 디펜던시를 추가하고 RabbitMQ를 설치한 환경에서 git Webhook으로

    깃에서 CURD가 이루어질때마다 push하게 한뒤

    git의 설정파일을 수정하면 @RefreshScope 이 있는 클래스의 값에 한해 수정과 동시에 클라이언트에 반영이 된다.

     

     

    문제점

    하지만,

    application_name.yml/properties 파일의 값만 그런 자동 새로고침이 된다.

    어플리케이션의 profile값을 설정했을 경우

    application_name-profile.yml/properites 형식의 파일도 읽을 수 있는데

    -profile이 붙은 파일들은 @RefreshScope 클래스에서도 수정과 동시에 읽을 수 없다.

    스프링 클라우드 컨피그 서버는 application 또는 applicaiton-profile 와 같이 application(이름), profile(프로필값), label(라벨값) 세가지를 이용해서 설정파일 이름을 짓거나 경로를 설정할수 있다.

     

    그래서 한 서비스를 위한 여러 설정파일을 두기 위해 프로필 값을 이용해야하는데

    application-profile.yml이 자동 새로고침이 안된다면 큰 문제다

     

    application 이름을 여러개로 해서

    appNm1.yml appNm2.yml, ...

    이렇게해도 1개만 자동 새로고침되고 나머지 파일들은 작동안했던것 같다.

     

     

    해결발상

    최후의 수단으로 어쩔수없이 강제로 새로고치게 장치를 만들어야 했다

     

    org.springframework.cloud:spring-cloud-config-monitor

    위 디펜던시를 사용하면 http://컨피그서버루트/monitor라는 엔드포인트를 제공한다.

     

    이 url로 body에 key: path, value: 서비스명(전체서비스는 *) 를 application_form_urlencoded로 전송하면

    서비스명.yml/properities 파일이 새로고침되서 클라이언트가 반영한다.

     

    git에서 수정이 일어나면 /monitor 엔드포인트로 path=*를 바디로 보내는 POST전송하게 해야 .yml의 이름과 상관없이 수정내용을 클라이언트가 반영할 수 있다.

     

    해결과정

    config server내에 새로운 엔드 포인트를 만들어서 그 안에서

    http://컨피그서버루트/monitor

    path=*를 보내주도록 했다.

     

    @PostMapping("/refreshAll")
      public String refreshAll(HttpServletRequest servletRequest){		  
        StringBuffer url = servletRequest.getRequestURL();
    	String uri = servletRequest.getRequestURI();
    	String target = url.toString().replaceAll(uri, "/monitor");
    	
    	RestTemplate restTemplate = new RestTemplate();
    	HttpHeaders headers = new HttpHeaders();
    	headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
    		
    	LinkedMultiValueMap<String, String> param =  new LinkedMultiValueMap<String, String>();	  
    	param.add("path", "*");
    		
    	HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(param, headers);		
    	ResponseEntity<String> response = restTemplate.postForEntity(target, request, String.class);
    		
    	return "targetUrl "+target;
    }

     

    -  서블릿리퀘스트 객체를 통해 컨피그 서버의 url을 가져오고 /monitor를 달아 타겟 url을 만든다

    -  RestTemplate 객체로 POST전송하기 위해 headers, body를 세팅해야함

    -  content-type: wxxx-application-form-urlencoded

     - body:  path(키), *(값)  맵 객체로 만들어보낸다

    -  RestTemplate 객체로 post하기 위해 url과 요청내용을 보낸다.

    - 리턴 스트링은 url이 맞는지 확인용

     

     

    이제 git에서 Webhook으로 위 메소드로 push하도록 해야한다.

    http://컨피그서버외부주소/매핑

    webhook에 등록하고 깃 설정파일을 수정하면

    수정후 바로 클라이언트에 반영된다. 이제 파일이름에 상관없이 모든 설정 수정사항을 빌드없이 바로 반영할수 잇다.

    댓글

Designed by Tistory.