Spring Cloud Config自動刷新配置


目錄

一、服務端配置

二、客戶端配置

三、客戶端使用

四、使用Gitlab Webhook自動刷新

五、Webhook測試異常

六、Webhook異常處理

一、服務端配置

增加SpringCloud bus等依賴:

pom.xml
1
2
3
4
5
6
7
8
9
<!-- springcloud-bus依賴實現配置自動更新,rabbitmq -->
< dependency >
     < groupId >org.springframework.cloud</ groupId >
     < artifactId >spring-cloud-starter-bus-amqp</ artifactId >
</ dependency >
< dependency >
     < groupId >org.springframework.boot</ groupId >
     < artifactId >spring-boot-starter-actuator</ artifactId >
</ dependency >

配置文件增加RabbitMQ地址、暴露節點等配置

bootstrap.yml
1
2
3
4
5
6
7
8
9
10
11
12
spring:
   # rabbitmq 地址配置
   rabbitmq:
     host:  172.18.0.118
     port:  32139
     username:  guest
     password:  guest
management:
   endpoints:
     web:
       exposure:
         include:  "*"

二、客戶端配置

添加SpringCloud bus等依賴

pom.xml
1
2
3
4
5
6
7
8
9
<!-- springcloud-bus依賴實現配置自動更新,rabbitmq -->
< dependency >
     < groupId >org.springframework.cloud</ groupId >
     < artifactId >spring-cloud-starter-bus-amqp</ artifactId >
</ dependency >
< dependency >
     < groupId >org.springframework.boot</ groupId >
     < artifactId >spring-boot-starter-actuator</ artifactId >
</ dependency >

配置文件增加RabbitMQ地址配置

bootstrap.yml
1
2
3
4
5
6
7
spring:
   # rabbitmq 地址配置
   rabbitmq:
     host:  172.18.0.118
     port:  32139
     username:  guest
     password:  guest

三、客戶端使用

增加@RefreshScope注解

Demo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@RestController
@RequestMapping ( "/ctrl" )
@RefreshScope
public  class  TestController {
 
 
     @Value ( "${chipcloud-service.endpoints.demo-test2.path:xxxxxxxxxxxxxx}" )
     private  String test;
 
     @RequestMapping ( "/test" )
     public  String getName(){
         System.out.println( "===================>" +test);
         return  "Success!" ;
     }
}

此時,當Config配置文件變化后,客戶端讀到的配置信息仍然是舊數據,需要手動請求   POST   http://配置中心IP:PORT/actuator/bus-refresh 觸發刷新。下面第四節通過Gitlab webhook代替該手動觸發POST請求(僅需在配置中心倉庫配置一次即可)。

四、使用Gitlab Webhook自動刷新

Gitlab→zkxy-config→Settings→Integrations

點擊Test→Push events進行測試:

 

五、Webhook測試異常

Push events進行測試,出現  400  的Http Status Code:

Request headers
Content-Type: application/json
X-Gitlab-Event: Push Hook
Request body  
{
   "object_kind" "push" ,
   "event_name" "push" ,
   "before" "243ce5486e9ef3ffa974337e550c0444daefa132" ,
   "after" "ddeb8cb816fe96905686deb0418be245aebc1c48" ,
   "ref" "refs/heads/master" ,
   "checkout_sha" "ddeb8cb816fe96905686deb0418be245aebc1c48" ,
   "message" null ,
   "user_id" : 11,
   "user_name" "zouxiaodong" ,
   "user_username" "zouxiaodong" ,
   "user_email" "" ,
   "project_id" : 14,
   "project" : {
     "id" : 14,
     "name" "zkxy-config" ,
     "description" "spring-cloud-config 分布式配置中心" ,
     "web_url" "http://172.18.0.103/proof/zkxy-config" ,
     "avatar_url" null ,
     "git_ssh_url" "git@172.18.0.103:proof/zkxy-config.git" ,
     "git_http_url" "http://172.18.0.103/proof/zkxy-config.git" ,
     "namespace" "proof" ,
     "visibility_level" : 20,
     "path_with_namespace" "proof/zkxy-config" ,
     "default_branch" "master" ,
     "ci_config_path" null ,
     "homepage" "http://172.18.0.103/proof/zkxy-config" ,
     "url" "git@172.18.0.103:proof/zkxy-config.git" ,
     "ssh_url" "git@172.18.0.103:proof/zkxy-config.git" ,
     "http_url" "http://172.18.0.103/proof/zkxy-config.git"
   },
   "commits" : [
     {
       "id" "ddeb8cb816fe96905686deb0418be245aebc1c48" ,
       "message" "解決webhook返回400錯誤碼的問題\n" ,
       "timestamp" "2020-09-02T07:44:13Z" ,
       "author" : {
         "name" "zouxiaodong" ,
         "email" "zouxd@chip-cloud.com"
       },
       "added" : [
         "src/main/java/com/zkxy/edaStation/zkxy_config/WebHooksFilter.java"
       ],
       "modified" : [
 
       ],
       "removed" : [
 
       ]
     }
   ],
   "total_commits_count" : 1,
   "push_options" : {
   },
   "repository" : {
     "name" "zkxy-config" ,
     "url" "git@172.18.0.103:proof/zkxy-config.git" ,
     "description" "spring-cloud-config 分布式配置中心" ,
     "homepage" "http://172.18.0.103/proof/zkxy-config" ,
     "git_http_url" "http://172.18.0.103/proof/zkxy-config.git" ,
     "git_ssh_url" "git@172.18.0.103:proof/zkxy-config.git" ,
     "visibility_level" : 20
   }
}
Response headers
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 02 Sep 2020 07:44:16 GMT
Connection: close
Response body
{"timestamp":"2020-09-02T07:44:16.576+0000","status":400,"error":"Bad Request","message":"JSON parse error: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token\n at [Source: (PushbackInputStream); line: 1, column: 459] (through reference chain: java.util.LinkedHashMap[\"project\"])","path":"/actuator/bus-refresh"}

六、Webhook異常處理

出現上述異常信息是因為POST請求會攜帶Request Body發送至配置中心服務器,Request Body使用JSON解析時出錯,無法反序列化,拋出異常,返回400錯誤。WebHook POST的請求附加的內容對於動態修改配置文件不重要,可以把附加的內容信息清空掉,這時JSON解析就不會出錯了。

通過Filter過濾器來攔截Http請求,清空servletRequest 中無法解析內容.

WebHooksFilter  
/**
 * @Description /actuator/bus-refresh 過濾器,清空/actuator/bus-refresh請求的Request body
 *
 * 解決Gitlab webhook觸發配置中心/actuator/bus-refresh請求返回400錯誤碼的問題
 *
 * Response body:
 * {"timestamp":"2020-09-02T07:21:31.728+0000","status":400,"error":"Bad Request","message":"JSON parse error: Cannot
 * deserialize instance of `java.lang.String` out of START_OBJECT token;
 * nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token\n at [Source: (PushbackInputStream);
 * line: 1, column: 459] (through reference chain: java.util.LinkedHashMap[\"project\"])","path":"/actuator/bus-refresh"}
 * @Author zouxiaodong
 * @Date 2020/09/02 15:25
 */
@Component
public class WebHooksFilter implements Filter {
 
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String url = httpServletRequest.getRequestURI();
        System.out.println("httpServletRequest.getRequestURI()=======>"+url);
        if(!url.endsWith("/bus-refresh")){
            filterChain.doFilter(servletRequest,servletResponse);
            return;
        }
        RequestWrapper requestWrapper = new RequestWrapper(httpServletRequest);
        filterChain.doFilter(requestWrapper, servletResponse);
    }
 
    private class RequestWrapper extends HttpServletRequestWrapper {
        public RequestWrapper(HttpServletRequest request) {
            super(request);
        }
 
        @Override
        public ServletInputStream getInputStream() throws IOException {
            byte[] bytes = new byte[0];
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
            ServletInputStream servletInputStream = new ServletInputStream() {
                @Override
                public int read() throws IOException {
                    return byteArrayInputStream.read();
                }
 
                @Override
                public boolean isFinished() {
                    return byteArrayInputStream.read() == -1 ? true : false;
                }
 
                @Override
                public boolean isReady() {
                    return false;
                }
 
                @Override
                public void setReadListener(ReadListener listener) {
 
                }
            };
            return servletInputStream;
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM