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