SpringCloud(九)——统一配置刷新(自动刷新)

SpringCloud(九)——统一配置刷新(自动刷新)

前言

在前几篇笔记中记录了统一配置中心的便捷刷新,总结来说是通过一些组件及第三方工具的帮助,然后再向统一配置服务发送POST请求的方式来完成刷新,虽然和以往相比要方便很多,但是依旧需要我们自行发送请求,如果统一配置中心也有多个节点,那么修改配置文件的操作将会变得更复杂,根据以往的操作方式并没有太好的办法。

所以,git为我们提供了一个组件——webhooks,该组件是将远端仓库的配置文件发生更改作为一个触发机制,然后执行发送请求的操作,恰巧的是该请求也是POST方式。

webhooks配置

webhooks是git中提供的一个工具,在对应的仓库中点击管理,然后在左侧边栏的下方找到WebHooks,点击进去可以看到如下界面:

在这里插入图片描述

接下来点击右上角添加WebHooks,可以看到以下界面:

在这里插入图片描述

**【注】:**到这里需要停一下,在之前给统一配置中心发送POST请求的时候,我们使用的是:localhost:${post}/actuator/busrefresh,可是git作为一个远端版本控制仓库,它无法识别我们所谓的localhost。如果想要其他服务器可以访问到我们本机电脑则需要一个公网IP。

这时候可以使用内网穿透来将自己的本机地址转化为一个公网IP,这里给大家提供一个免费的内网穿透软件——natapp

natapp配置步骤

  • 免费注册

在这里插入图片描述

  • 接下来就是常规的注册步骤,在此不做赘述。但是一定要做实名认证,这种网络相关的工具和插件现在必须进行实名认证。
  • 实名认证结束后可以点击购买隧道(什么是隧道总结里说),在购买隧道里仅仅需要配置一个自己记得住的隧道名即可,其余的配置都可以后期更改。

在这里插入图片描述

  • 购买结束后,可以在我的隧道里面看到对应的隧道:

在这里插入图片描述

  • 点击配置可以看到隧道的详细配置,暂时使用的仅仅是本地地址和本地端口,与统一配置中心的路径相同。

在这里插入图片描述

  • 然后在官网中下载对应的natapp客户端,根据自己的电脑系统选择下载,在此不做赘述。
  • 下载成功后将文件放在全英文路径下,然后配置对应的成员变量,如下所示:

在这里插入图片描述

  • cmd命令提示符窗口中启动该软件,在此之前要复制一下隧道列表中的authtoken,然后输入一下命令:
natapp -authtoken=${复制好的authtoken}
  • 启动后的页面中会显示为我们转化过后的IP:

在这里插入图片描述

PS:图中马赛克部分就是转化后的IP,注意该IP表示的是:localhost:8091,即在此发送请求的时候不需要加入端口号。

  • 在WebHooks界面中把转化后的IP写入,并下图操作:

在这里插入图片描述

  • 在我们点击添加后,会发现发送的请求出现400错误,这时需要通过在统一配置中心添加过滤器来操作(具体原因是复杂数据类型的JSON与String转化问题,下面提供给大家过滤器的代码):
@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/busrefresh请求
        // 如果使用的SpringCloud为20版本之前则需要将该字符串修改为 : /bus-refresh
        if (!url.endsWith("/busrefresh")) {
            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();
    }
}

添加过滤器后在入口类添加可以识别该过滤器的注解

@ServletComponentScan(basePackages = "com.xxx.filters")
  • 重启服务过后可以重新测试WebHooks。

在这里插入图片描述

总结

所谓隧道,可以单纯的理解为一个URL与对应转化公网IP的沟通桥梁,这种沟通时单线联系,别人无法插手进来,这样可以保证安全。为什么要使用隧道的手段,大家可以去看谍战片。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值