zoukankan      html  css  js  c++  java
  • 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 分布式配置中心",
        "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,
        "url""git@172.18.0.103:proof/zkxy-config.git",
        "ssh_url""git@172.18.0.103:proof/zkxy-config.git",
      },
      "commits": [
        {
          "id""ddeb8cb816fe96905686deb0418be245aebc1c48",
          "message""解决webhook返回400错误码的问题 ",
          "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 分布式配置中心",
        "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 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
     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;
            }
        }
    }

     
  • 相关阅读:
    做最简单的自定义控件!
    DataGridView取消默认选中行
    好看的vs皮肤
    rdlc插入图像(.net2010)
    学习c#反射的一个例子
    C#Winform中ToolTip的简单用法
    rdlc报表显示条码 .
    vb.net ctype用法
    一些常用的正则表达式 .
    C# WinForm中MenuStrip动态菜单使用总结
  • 原文地址:https://www.cnblogs.com/Java-Script/p/13902245.html
Copyright © 2011-2022 走看看