【SpringCloud】搭建高可用分布式配置中心(Spring Cloud Config)(二)全过程详解(自动刷新)解决webhooks 400错误

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_42684642/article/details/86530761

本文基于第一篇搭建好手动刷新的基础上进行的自动刷新。详见(一)全过程详解(手动刷新)

在搭建好第一步的手动更新的配置中心之后,要实现自动更新就很简单了。

一. config-client添加依赖

pom.xml文件中添加:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
            <version>2.0.0.RELEASE</version>
        </dependency>

二. 配置文件application.yml文件增加配置

application.yml文件配置:

spring:
  rabbitmq:
   host: localhost
   port: 5672
   username: user
   password: password
  cloud:
    bus:
      trace:
        enabled: true
      enabled: true

三. Gitee码云上添加webhooks

需要注意的是:

1.需要有公网ip,码云上需要使用公网ip进行访问(我使用的frp进行的内网穿透,感兴趣的同学可以自己尝试下)

2.访问地址的后缀为 /actuator/bus-refresh

如图所示,即可成功配置。

四.运行即可看到已经自动刷新配置了。

五. ERROR解决

{"timestamp":"2019-01-17T12:33:34.975+0000","status":400,"error":"Bad Request","message":"JSON parse error: Cannot deserialize instance of `java.lang.String` out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_ARRAY token\n at [Source: (PushbackInputStream); line: 1, column: 326] (through reference chain: java.util.LinkedHashMap[\"commits\"])","path":"/actuator/bus-refresh"}

有不少同学配置之后却无法自动刷新,发现报400 error的错误,如图。

这是因为spring boot无法正常反序列化造成,我们需要写一个过滤器将Body直接返回为空,就可以达到过滤body的效果。

@Component
public class UrlFilter  implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest)request;
        HttpServletResponse httpServletResponse = (HttpServletResponse)response;

        String url = new String(httpServletRequest.getRequestURI());

        //只过滤/actuator/bus-refresh请求
        if (!url.endsWith("/bus-refresh")) {
            chain.doFilter(request, response);
            return;
        }

        //获取原始的body
        String body = readAsChars(httpServletRequest);

        System.out.println("original body:   "+ body);

        //使用HttpServletRequest包装原始请求达到修改post请求中body内容的目的
        CustometRequestWrapper requestWrapper = new CustometRequestWrapper(httpServletRequest);

        chain.doFilter(requestWrapper, response);

    }

    @Override
    public void destroy() {

    }

    private class CustometRequestWrapper extends HttpServletRequestWrapper {
        public CustometRequestWrapper(HttpServletRequest request) {
            super(request);
        }

        @Override
        public ServletInputStream getInputStream() throws IOException {
            byte[] bytes = new byte[0];
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);

            return new ServletInputStream() {
                @Override
                public boolean isFinished() {
                    return byteArrayInputStream.read() == -1 ? true:false;
                }

                @Override
                public boolean isReady() {
                    return false;
                }

                @Override
                public void setReadListener(ReadListener readListener) {

                }

                @Override
                public int read() throws IOException {
                    return byteArrayInputStream.read();
                }
            };
        }
    }

    public static String readAsChars(HttpServletRequest request)
    {

        BufferedReader br = null;
        StringBuilder sb = new StringBuilder("");
        try
        {
            br = request.getReader();
            String str;
            while ((str = br.readLine()) != null)
            {
                sb.append(str);
            }
            br.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (null != br)
            {
                try
                {
                    br.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }
}

 再次运行项目,测试webhooks,可以发现成功返回 

 

控制台也成功打印出原来的body。

六.总结

很多人没有自动更新的原因可能就是webhooks这边出错,这个方法还是参考的https://blog.csdn.net/m0_37556444/article/details/82812816,感谢博主,这边写出来大家也一起分享下经验。

猜你喜欢

转载自blog.csdn.net/qq_42684642/article/details/86530761