SpringCloud学习之Config—动态更新配置

发布于:2023-01-20 ⋅ 阅读:(17) ⋅ 点赞:(0) ⋅ 评论:(0)

1.Config的简介

springCloud Config 是一个解决分布式系统的配置管理方案,是SpringCloud的配置中心组件,可集中管理配置文件,是客户端和服务器端CS模式,其配置文件基于Git的。

在这里插入图片描述

2.Config的使用

1.创建一个新仓库存放各项目的Config配置

2.新建本次项目的文件夹,在git仓库中提交mysql-product-service服务的配置文件mysql-product-service-dev.properties
在这里插入图片描述

命名规则:服务名称-profile名称(dev/test/prod).properties或yml

server.port=9003

#设置jdbc配置
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/feign_product?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root

#映射文件
mybatis-plus.mapper-locations= classpath:mapper/*.xml
#开启驼峰转换
mybatis-plus.configuration.map-underscore-to-camel-case=true
#开启别名
mybatis-plus.type-aliases-package=com.blb.mysql_product_service.entity
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

#服务名称
spring.application.name=mysql-product-server
#配置是否注册到Eureka
eureka.client.register-with-eureka=true
#配置是否从Eureka拉取服务清单
eureka.client.fetch-registry=true
#配置地址
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8888/eureka/

3.搭建Config服务器

1) 在config-service模块引入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

2)启动类上加上@EnableDiscoveryClient(加入eureka注册中心)以及@EnableConfigServer注解

3)编写配置文件

server.port=6666
spring.application.name=config-server
#是否从注册中心获得数据
eureka.client.fetch-registry=true
#是否注册到注册中心上
eureka.client.register-with-eureka=true
#配置注册中心的地址
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8888/eureka/
#配置中心git相关配置
spring.cloud.config.server.git.uri=自己的git仓库URL
spring.cloud.config.server.git.username=自己的账号
spring.cloud.config.server.git.password=自己的密码
#配置文件存放的目录,如果是根目录可以不配置
spring.cloud.config.server.git.search-paths=20220808_springcloud
#分支名称
spring.cloud.config.label=master

4.搭建Config客户端

1)在需要config的模块引入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-client</artifactId>
</dependency>

2)将原本application改名为bootstrap(bootstrap会优先于application加载,这是约定大于配置)

server.port=9003
#应用程序名
spring.application.name=mysql-product-service
#是否从注册中心获得数据
eureka.client.fetch-registry=true
#是否注册到注册中心上
eureka.client.register-with-eureka=true
#配置注册中心的地址
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8888/eureka/

#配置中心服务器的配置
spring.cloud.config.discovery.service-id=config-server
#启动配置中心的发现机制
spring.cloud.config.discovery.enabled=true
#配置profile  不写profile 填default
spring.cloud.config.profile=dev
#配置分支
spring.cloud.config.label=master

#开启全部端点
management.endpoints.web.exposure.include=* 

3) 新增controller层文件,注入配置内容(用于测试)

访问 http://服务ip:端口/product/config查看Config是否生效

@RestController
@RefreshScope
public class ConfigController {
    @Value("${spring.datasource.driver-class-name}")
    private String driverName;

    @Value("${spring.datasource.url}")
    private String url;

    @Value("${spring.datasource.username}")
    private String username;

    @Value("${spring.datasource.password}")
    private String password;

    @GetMapping("/product/config")
    public String config(){
        return driverName + " " + url;
    }
}

在这里插入图片描述

5.动态更新配置

配置文件更新后,客户端需要获得最新的配置

5.1手动更新

1)客户端引入依赖 actuator

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

2)在需要进行动态更新配置的类上加 @RefreshScope

3)开启端点,在配置文件中加入配置

#开启全部端点
management.endpoints.web.exposure.include=* 

4)修改git配置文件,发送post请求进行手动更新

http://服务ip:端口/actuator/refresh

5)访问 http://服务ip:端口/product/config查看手动更新是否生效

5.2自动更新

使用自动更新后,无需每次都发送post请求进行手动更新即可获得最新配置

在这里插入图片描述

1) 在git仓库中配置Webhook,使用内网穿透进行测试,按个人喜好选择穿透工具即可。

此时git会自动发送一个请求到当前路径,会报错400,因为码云的钩子有问题

解决方案:

  • 启动类加@ServletComponentScan
  • 在客户端编写CustometRequestWrapper与Filter配置文件
public 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();
            }
        };
    }

}
@WebFilter(filterName = "bodyFilter", urlPatterns = "/*")
@Order(1)
public class MyFlter  implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest;
        String url = new String(httpServletRequest.getRequestURI());
        //只过滤/actuator/refresh请求
        if (!url.endsWith("/actuator/refresh")) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }
        //使用HttpServletRequest包装原始请求达到修改post请求中body内容的目的
        CustometRequestWrapper requestWrapper = new CustometRequestWrapper(httpServletRequest);
        filterChain.doFilter(requestWrapper, servletResponse);
    }

    @Override
    public void destroy() {

    }
}

2)配置完成后重新在Webhook进行测试,此时请求成功

在这里插入图片描述

3) 测试

​ 在远程仓库修改配置文件,然后访问 http://服务ip:端口/product/config查看自动更新是否生效。

5.3使用消息总线Bus+RabbitMQ实现自动更新

当有好几个服务器都需要拉取Config时,如果用普通的自动更新则需要每个都配置Webhook来拉取,比较麻烦,所以可以使用消息队列来统一拉取。
Bus是SpringCloud的消息总线,可以借助消息队列(RabbitMQ)进行消息广播,在Config服务端拉取各自所需的最新配置。
在这里插入图片描述

  1. 安装RabbitMQ,并启动。安装教程点击查看

2)Config服务端跟客户端都需要添加以下依赖

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

注意:服务端还需要actuator依赖

3)Config服务和客户端都添加配置(默认为以下配置)

spring:
	rabbitmq:
		host: 127.0.0.1
		port: 5672 
		username: guest 
		password: guest

4)Config服务暴露端点(客户端可以不暴露)

management.endpoints.web.exposure.include=* 

5) Webhook 向Config服务发送post请求

http://内网穿透Config服务端端口/actuator/bus-refresh

出现400错误同之前一样处理

  • 服务端启动类加@ServletComponentScan(由于是统一拉取,所以之前在客户端上的这个注解可以删掉)
  • 在服务端编写CustometRequestWrapper与Filter配置文件(之前在客户端的配置文件也可以注释)
    注意: 修改过滤器中 url.endsWith(“/actuator/bus-refresh”))

===========以上就是本人整理的Config配置中心的使用,感谢查阅~ ==============