`

[转]spring cloud config实现datasource的热部署

 
阅读更多

转自:http://blog.csdn.net/liuchuanhong1/article/details/75446850

关于spring cloud config的基本使用,前面的博客中已经说过了,如果不了解的话,请先看以前的博客

spring cloud config整合gitlab搭建分布式的配置中心

spring cloud config分布式配置中心的高可用

今天,我们的重点是如何实现数据源的热部署。

1、在客户端配置数据源

 

[java] view plain copy
 
  1. @RefreshScope  
  2. @Configuration// 配置数据源  
  3. public class DataSourceConfigure {  
  4.   
  5.     @Bean  
  6.     @RefreshScope// 刷新配置文件  
  7.     @ConfigurationProperties(prefix="spring.datasource"// 数据源的自动配置的前缀  
  8.     public DataSource dataSource(){  
  9.         return DataSourceBuilder.create().build();  
  10.     }  
  11. }  


通过上面的几个步骤,就可以实现在gitlab上修改配置文件,刷新后,服务器不用重启,新的数据源就会生效。

 

2、自定义数据源的热部署

当我们使用spring boot集成druid,我们需要手动来配置数据源,代码如下:

 

[java] view plain copy
 
  1. package com.chhliu.springcloud.config;  
  2.   
  3. import java.sql.SQLException;  
  4.   
  5. import javax.sql.DataSource;  
  6.   
  7. import org.springframework.beans.factory.annotation.Value;  
  8. import org.springframework.cloud.context.config.annotation.RefreshScope;  
  9. import org.springframework.context.annotation.Bean;  
  10. import org.springframework.context.annotation.Configuration;  
  11. import org.springframework.context.annotation.Primary;  
  12.   
  13. import com.alibaba.druid.pool.DruidDataSource;  
  14.   
  15. import lombok.extern.slf4j.Slf4j;  
  16.   
  17. /** 
  18.  *  
  19.  * 描述:如果不使用代码手动初始化DataSource的话,监控界面的SQL监控会没有数据("是spring boot的bug???") 
  20.  * @author chhliu 
  21.  * 创建时间:2017年2月9日 下午7:33:08 
  22.  * @version 1.2.0 
  23.  */  
  24. @Slf4j  
  25. @Configuration  
  26. @RefreshScope  
  27. public class DruidConfiguration {  
  28.     @Value("${spring.datasource.url}")  
  29.     private String dbUrl;  
  30.     @Value("${spring.datasource.username}")  
  31.     private String username;  
  32.     @Value("${spring.datasource.password}")  
  33.     private String password;  
  34.     @Value("${spring.datasource.driverClassName}")  
  35.     private String driverClassName;  
  36.     @Value("${spring.datasource.initialSize}")  
  37.     private int initialSize;  
  38.     @Value("${spring.datasource.minIdle}")  
  39.     private int minIdle;  
  40.     @Value("${spring.datasource.maxActive}")  
  41.     private int maxActive;  
  42.     @Value("${spring.datasource.maxWait}")  
  43.     private int maxWait;  
  44.     @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")  
  45.     private int timeBetweenEvictionRunsMillis;  
  46.     @Value("${spring.datasource.minEvictableIdleTimeMillis}")  
  47.     private int minEvictableIdleTimeMillis;  
  48.     @Value("${spring.datasource.validationQuery}")  
  49.     private String validationQuery;  
  50.     @Value("${spring.datasource.testWhileIdle}")  
  51.     private boolean testWhileIdle;  
  52.     @Value("${spring.datasource.testOnBorrow}")  
  53.     private boolean testOnBorrow;  
  54.     @Value("${spring.datasource.testOnReturn}")  
  55.     private boolean testOnReturn;  
  56.     @Value("${spring.datasource.poolPreparedStatements}")  
  57.     private boolean poolPreparedStatements;  
  58.     @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")  
  59.     private int maxPoolPreparedStatementPerConnectionSize;  
  60.     @Value("${spring.datasource.filters}")  
  61.     private String filters;  
  62.     @Value("${spring.datasource.connectionProperties}")  
  63.     private String connectionProperties;  
  64.     @Value("${spring.datasource.useGlobalDataSourceStat}")  
  65.     private boolean useGlobalDataSourceStat;  
  66.   
  67.     @Bean     //声明其为Bean实例  
  68.     @Primary  //在同样的DataSource中,首先使用被标注的DataSource  
  69.     @RefreshScope  
  70.     public DataSource dataSource(){  
  71.         DruidDataSource datasource = new DruidDataSource();  
  72.         datasource.setUrl(this.dbUrl);  
  73.         datasource.setUsername(username);  
  74.         datasource.setPassword(password);  
  75.         datasource.setDriverClassName(driverClassName);  
  76.   
  77.         //configuration  
  78.         datasource.setInitialSize(initialSize);  
  79.         datasource.setMinIdle(minIdle);  
  80.         datasource.setMaxActive(maxActive);  
  81.         datasource.setMaxWait(maxWait);  
  82.         datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);  
  83.         datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);  
  84.         datasource.setValidationQuery(validationQuery);  
  85.         datasource.setTestWhileIdle(testWhileIdle);  
  86.         datasource.setTestOnBorrow(testOnBorrow);  
  87.         datasource.setTestOnReturn(testOnReturn);  
  88.         datasource.setPoolPreparedStatements(poolPreparedStatements);  
  89.         datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);  
  90.         datasource.setUseGlobalDataSourceStat(useGlobalDataSourceStat);  
  91.         try {  
  92.             datasource.setFilters(filters);  
  93.         } catch (SQLException e) {  
  94.             log.error("druid configuration initialization filter: "+ e);  
  95.         }  
  96.         datasource.setConnectionProperties(connectionProperties);  
  97.         return datasource;  
  98.     }  
  99. }  


通过上面的示例,也可以实现数据源的动态刷新。接下来,我们就来看看,spring cloud config是怎么来实现数据源的热部署的。

 

从前面的博客中,我们不难发现,要想实现动态刷新,关键点就在post refresh的请求上,那我们就从刷新配置文件开始。

当我们post刷新请求的时候,这个请求会被actuator模块拦截,这点从启动的日志文件中就可以看出

 

[java] view plain copy
 
  1. Mapped "{[/refresh || /refresh.json],methods=[POST]}" onto public java.lang.Object org.springframework.cloud.endpoint.GenericPostableMvcEndpoint.invoke()  


接下来,我们就来看actuator定义的EndPoint,然后我们就找到了RefreshEndpoint这个类,该类的源码如下:

 

 

[java] view plain copy
 
  1. @ConfigurationProperties(prefix = "endpoints.refresh", ignoreUnknownFields = false)  
  2. @ManagedResource  
  3. public class RefreshEndpoint extends AbstractEndpoint<Collection<String>> {  
  4.   
  5.     private ContextRefresher contextRefresher;  
  6.   
  7.     public RefreshEndpoint(ContextRefresher contextRefresher) {  
  8.         super("refresh");  
  9.         this.contextRefresher = contextRefresher;  
  10.     }  
  11.   
  12.     @ManagedOperation  
  13.     public String[] refresh() {  
  14.         Set<String> keys = contextRefresher.refresh();  
  15.         return keys.toArray(new String[keys.size()]);  
  16.     }  
  17.   
  18.     @Override  
  19.     public Collection<String> invoke() {  
  20.         return Arrays.asList(refresh());  
  21.     }  
  22.   
  23. }  


从上面的源码,我们可以看到,重点在ContextRefresher这个类上,由于这个类太长了,下面把这个类的部分源码贴出来:

 

 

[java] view plain copy
 
  1. private RefreshScope scope;  
  2.   
  3.     public ContextRefresher(ConfigurableApplicationContext context, RefreshScope scope) {  
  4.         this.context = context;  
  5.         this.scope = scope;  
  6.     }  
  7.   
  8.     public synchronized Set<String> refresh() {  
  9.         Map<String, Object> before = extract(  
  10.                 this.context.getEnvironment().getPropertySources());// 1、before,加载提取配置文件  
  11.         addConfigFilesToEnvironment();// 2、将配置文件加载到环境中  
  12.         Set<String> keys = changes(before,  
  13.                 extract(this.context.getEnvironment().getPropertySources())).keySet();// 3、替换原来环境变量中的值  
  14.         this.context.publishEvent(new EnvironmentChangeEvent(keys));// 4、发布变更事件,  
  15.         this.scope.refreshAll();  
  16.         return keys;  
  17.     }  


从上面的代码不难看出,重点经历了4个步骤,上面代码中已标注。

分享到:
评论

相关推荐

    详解spring cloud config实现datasource的热部署

    "Spring Cloud Config实现Datasource热部署详解" Spring Cloud Config是一款基于分布式配置中心的解决方案,它可以帮助我们管理和维护微服务架构中的配置信息。今天,我们将讨论如何使用Spring Cloud Config实现...

    spring cloud config 和 bus 源码解读

    总结来说,Spring Cloud Config提供了集中化的外部配置管理,而Spring Cloud Bus则扩展了Spring Cloud Config的功能,实现了配置的动态刷新。本文从源码角度解读了Config Server的初始化过程、配置获取处理以及Bus的...

    Spring cloud config 配置文件加密方式

    Spring Cloud Config 配置文件加密方式 Spring Cloud Config 是一个基于云计算的配置中心,它提供了对应用程序配置的集中管理和加密。配置文件加密是 Spring Cloud Config 的一个重要特性,它可以保护敏感数据不被...

    spring-cloud-alibaba-sentinel-datasource-2021.1-API文档-中文版.zip

    赠送jar包:spring-cloud-alibaba-sentinel-datasource-2021.1.jar; 赠送原API文档:spring-cloud-alibaba-sentinel-datasource-2021.1-javadoc.jar; 赠送源代码:spring-cloud-alibaba-sentinel-datasource-2021....

    spring-cloud 集成 flowable 工作流

    为了在Spring Cloud服务中使用Flowable,我们需要编写服务接口和实现,用于启动、查询、参与等工作流操作。例如,我们可以创建一个`WorkflowService`,提供`startProcessInstanceByKey`方法来根据流程定义的key启动...

    初学SpringCloud连接Oracle数据库

    在初学SpringCloud的过程中,与Oracle数据库的连接是构建分布式系统的一个重要环节。SpringCloud作为一个微服务框架,提供了丰富的服务治理功能,而数据库作为数据存储的核心,与SpringBoot的集成使得我们可以轻松...

    springcloud入门

    6、MYSQL(执行springcloud-producer目录src/main/resources/templates/datasource.text中的建表语句) #### 使用说明 项目运行顺序: 1、 springcloud-register, 2、 springcloud-config-native或者springcloud-...

    spring cloud整合mybatis

    在Spring Cloud生态系统中,整合MyBatis作为持久层框架是一个常见的需求。这允许开发者利用Spring Cloud的强大服务发现和治理功能,结合MyBatis的灵活数据库操作能力,构建微服务架构的应用程序。以下将详细介绍如何...

    spring-cloud-alibaba-sentinel-datasource-2021.1-API文档-中英对照版.zip

    赠送jar包:spring-cloud-alibaba-sentinel-datasource-2021.1.jar; 赠送原API文档:spring-cloud-alibaba-sentinel-datasource-2021.1-javadoc.jar; 赠送源代码:spring-cloud-alibaba-sentinel-datasource-2021....

    Spring动态切换datasource实现mysql多住多从

    "Spring动态切换datasource实现mysql多主多从"是针对大型分布式系统中数据读写分离、负载均衡的一种常见策略。该技术使得应用程序能够在运行时根据业务需求灵活地选择不同的数据源,从而提高系统的可扩展性和可用性...

    2020最新版SpringCloud(H版&alibaba)框架开发教程全套完整版从入门到精通(121-150讲).rar

    2020最新版SpringCloud(H版&alibaba)框架开发教程全套完整版从入门到精通(121-150讲)

    详解SpringCloud mysql实现配置中心

    Spring Cloud Config满足了以上所有需求,可以实现配置中心的功能。 二、配置中心的实现 配置中心微服务使用Spring Boot框架来实现,pom.xml文件中需要添加以下依赖项: * spring-cloud-starter-netflix-eureka-...

    spring-cloud-connectors-master.zip

    1. **服务发现**:Spring Cloud Connectors通过读取环境变量或配置文件,自动发现应用部署在云环境中的服务实例。 2. **自动配置**:一旦服务被发现,Connectors会自动生成相应的配置,将这些配置注入到Spring应用...

    微服务架构:Spring-Cloud汇总.pdf

    Spring Cloud是实现微服务架构的一套框架,它提供了许多工具和服务,以简化微服务的开发和管理。Spring Cloud基于Spring Boot,使得创建和配置微服务变得简单易行。Spring Boot是一个快速开发框架,用于简化Spring...

    Spring Cloud集成MyBaties-Plus.pdf

    Spring Cloud集成MyBatis-Plus是一项常见的微服务开发任务,旨在利用MyBatis-Plus的便利性增强Spring Cloud应用的数据访问能力。MyBatis-Plus是MyBatis的扩展库,它简化了许多常见的MyBatis操作,如CRUD操作、条件...

    spring_cloud.rar

    3. **Eureka目录**:服务注册与发现是Spring Cloud的基础,Eureka是实现这一功能的组件,这里可能会有Eureka Server的配置和客户端代码。 4. **Ribbon目录**:Ribbon是客户端负载均衡器,用于在服务间进行请求分发,...

    springCloud.docx

    Spring Cloud 是一系列框架的有序集合,它利用了Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,并且都基于Spring Boot实现。...

    基于maven的SpringCloud初始项目

    该项目为自己使用maven搭建的一个初始的SpringCloud项目,该项目用于节约搭建时间。 已发布于Gitee。 软件架构 项目内容包括三部分: (1)父工程 (2)子工程orderService (3)子工程userService 安装和启动教程...

    Java学习SpringCloud - 整合Seata实现分布式事务

    本篇文章将详细探讨如何在Spring Cloud项目中整合Seata,实现分布式事务的处理。 首先,我们需要了解分布式事务的基本概念。在单体应用中,事务管理相对简单,但在分布式系统中,由于多个服务间的交互,确保数据的...

Global site tag (gtag.js) - Google Analytics