Spring Cloud Config 整合Spring Cloud Bus以及使用WebHooks 实现自动更新

版本真的很重要!!!

整合config和bus 期间我遇到以下问题:

1. spring cloud 版本和spring boot版本不兼容,有些类找不到,以至于启动不了

2. 使用spring-cloud-starter-bus-amqp时,使用bus-refresh时没有互相推送,actuator的接口没有对外暴露

3. 使用WebHooks将git文件修改推送到 xxx/actuator/bus/refresh上,报了400

下面就到了 show code:

首先我使用的spring cloud version : GreenWich.RC2   ;spring boot version : 2.1.3.RELEASE

重点说下bus-refresh地址: 一定不要错,国内很多调用信息都是老版本

参考官网:https://cloud.spring.io/spring-cloud-bus/single/spring-cloud-bus.html#_bus_refresh_endpoint

curl -v -X POST "http://localhost:9001/actuator/bus-refresh"

先贴 config server端的 yml:  

spring:
  application:
    name: config
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/xxx/xxx
          username: xxx
          password: xxx
          basedir: C:/Users/xie87/Desktop/repo/
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
management:
  endpoints:
    web:
      exposure:
        include: "*"  #为了暴露actuator的接口

config server的依赖:(actuator 用来监控和刷新)


  org.springframework.boot
  spring-boot-starter-actuator
 

  org.springframework.cloud
  spring-cloud-starter-bus-amqp


   org.springframework.cloud
   spring-cloud-config-server


  org.springframework.cloud
  spring-cloud-starter-netflix-eureka-client

config server端的代码

@SpringBootApplication
@EnableDiscoveryClient
@EnableConfigServer
public class ConfigApplication {
    run..
}

写一个过滤器,过滤掉下面的这个请求,为了让WebHooks正常发送请求

/actuator/bus-refresh

随便找了一个过滤器,代码附上

package com.seller.config;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ReadListener;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;

/**
 * 过滤器
 */
@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("/actuator/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();
  }
}

 

order的yml:

spring:
  application:
    name: order
  cloud:
    config:
      discovery:
        enabled: true
        service-id: CONFIG
      profile: dev
eureka:
  client:
    service-url:
      defaultZone: http://eureka1:8761/eureka/
management:
  endpoints:
    web:
      exposure:
        include:  bus-refresh # 暴露bus-refresh为了接到通知

客户端order的pom:(核心包)


   org.springframework.boot
   spring-boot-starter-actuator


   org.springframework.cloud
   spring-cloud-config-client


    org.springframework.cloud
    spring-cloud-starter-bus-amqp

order代码;

@SpringBootApplication
@EnableDiscoveryClient
public class OrderApplication {
    run..
}

测试接口

@RestController
@RefreshScope
public class TestController {
  @Value("${name}")
  private String name;

  @GetMapping("/print")
  public String print() {
    return name;
  }

}

下面看gitee 仓库,name: very good!!

Spring Cloud Config 整合Spring Cloud Bus以及使用WebHooks 实现自动更新_第1张图片

调用接口:

1. 修改文件值

2.gitee WebHook推送了信息:

3.本地config server 端刷新了日志

4.order端接受到修改信息,解析,重新获取,局部刷新

2019-03-02 20:23:19.839  INFO 12028 --- [jSNlPxJXhyu1w-1] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$164481ed] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2019-03-02 20:23:20.741  INFO 12028 --- [jSNlPxJXhyu1w-1] o.s.c.n.eureka.InstanceInfoFactory       : Setting initial instance status as: STARTING
2019-03-02 20:23:20.746  INFO 12028 --- [jSNlPxJXhyu1w-1] com.netflix.discovery.DiscoveryClient    : Initializing Eureka in region us-east-1
2019-03-02 20:23:20.749  INFO 12028 --- [jSNlPxJXhyu1w-1] c.n.d.provider.DiscoveryJerseyProvider   : Using JSON encoding codec LegacyJacksonJson
2019-03-02 20:23:20.749  INFO 12028 --- [jSNlPxJXhyu1w-1] c.n.d.provider.DiscoveryJerseyProvider   : Using JSON decoding codec LegacyJacksonJson
2019-03-02 20:23:20.749  INFO 12028 --- [jSNlPxJXhyu1w-1] c.n.d.provider.DiscoveryJerseyProvider   : Using XML encoding codec XStreamXml
2019-03-02 20:23:20.749  INFO 12028 --- [jSNlPxJXhyu1w-1] c.n.d.provider.DiscoveryJerseyProvider   : Using XML decoding codec XStreamXml
2019-03-02 20:23:20.915  INFO 12028 --- [jSNlPxJXhyu1w-1] c.n.d.s.r.aws.ConfigClusterResolver      : Resolving eureka endpoints via configuration
2019-03-02 20:23:20.917  INFO 12028 --- [jSNlPxJXhyu1w-1] com.netflix.discovery.DiscoveryClient    : Disable delta property : false
2019-03-02 20:23:20.917  INFO 12028 --- [jSNlPxJXhyu1w-1] com.netflix.discovery.DiscoveryClient    : Single vip registry refresh property : null
2019-03-02 20:23:20.917  INFO 12028 --- [jSNlPxJXhyu1w-1] com.netflix.discovery.DiscoveryClient    : Force full registry fetch : false
2019-03-02 20:23:20.917  INFO 12028 --- [jSNlPxJXhyu1w-1] com.netflix.discovery.DiscoveryClient    : Application is null : false
2019-03-02 20:23:20.917  INFO 12028 --- [jSNlPxJXhyu1w-1] com.netflix.discovery.DiscoveryClient    : Registered Applications size is zero : true
2019-03-02 20:23:20.917  INFO 12028 --- [jSNlPxJXhyu1w-1] com.netflix.discovery.DiscoveryClient    : Application version is -1: true
2019-03-02 20:23:20.917  INFO 12028 --- [jSNlPxJXhyu1w-1] com.netflix.discovery.DiscoveryClient    : Getting all instance registry info from the eureka server
2019-03-02 20:23:20.924  INFO 12028 --- [jSNlPxJXhyu1w-1] com.netflix.discovery.DiscoveryClient    : The response status is 200
2019-03-02 20:23:20.924  INFO 12028 --- [jSNlPxJXhyu1w-1] com.netflix.discovery.DiscoveryClient    : Not registering with Eureka server per configuration
2019-03-02 20:23:20.924  INFO 12028 --- [jSNlPxJXhyu1w-1] com.netflix.discovery.DiscoveryClient    : Discovery Client initialized at timestamp 1551529400924 with initial instances count: 2
2019-03-02 20:23:21.548  INFO 12028 --- [jSNlPxJXhyu1w-1] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://DESKTOP-2N9C4AE:9001/
2019-03-02 20:23:23.276  INFO 12028 --- [jSNlPxJXhyu1w-1] c.c.c.ConfigServicePropertySourceLocator : Located environment: name=order, profiles=[dev], label=null, version=76e1c9035d8d89d0c545e2e24130904ff43d4ef6, state=null
2019-03-02 20:23:23.276  INFO 12028 --- [jSNlPxJXhyu1w-1] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource {name='configService', propertySources=[MapPropertySource {name='configClient'}, MapPropertySource {name='https://gitee.com/xiechenxuyuan/SpringCouldConfig/order-dev.yml'}]}
2019-03-02 20:23:23.278  INFO 12028 --- [jSNlPxJXhyu1w-1] o.s.boot.SpringApplication               : No active profile set, falling back to default profiles: default
2019-03-02 20:23:23.289  INFO 12028 --- [jSNlPxJXhyu1w-1] o.s.boot.SpringApplication               : Started application in 4.941 seconds (JVM running for 189.325)
2019-03-02 20:23:23.289  INFO 12028 --- [jSNlPxJXhyu1w-1] com.netflix.discovery.DiscoveryClient    : Shutting down DiscoveryClient ...
2019-03-02 20:23:23.292  INFO 12028 --- [jSNlPxJXhyu1w-1] com.netflix.discovery.DiscoveryClient    : Completed shut down of DiscoveryClient
2019-03-02 20:23:23.431  INFO 12028 --- [jSNlPxJXhyu1w-1] com.netflix.discovery.DiscoveryClient    : Shutting down DiscoveryClient ...
2019-03-02 20:23:23.835  INFO 12028 --- [jSNlPxJXhyu1w-1] com.netflix.discovery.DiscoveryClient    : Unregistering ...

5.查看页面,数据已刷新


Studies this matter,lacks the time ,but is lacks diligently。

学习这件事,不是缺乏时间,而是缺乏努力。

 

 

 

你可能感兴趣的:(异常,Spring,Cloud)