温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

spring cloud config如何实现datasource热部署

发布时间:2021-08-06 11:26:32 来源:亿速云 阅读:163 作者:小新 栏目:编程语言

这篇文章主要介绍spring cloud config如何实现datasource热部署,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

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

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

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

1、在客户端配置数据源

@RefreshScope 
@Configuration// 配置数据源 
public class DataSourceConfigure { 
 
  @Bean 
  @RefreshScope// 刷新配置文件 
  @ConfigurationProperties(prefix="spring.datasource") // 数据源的自动配置的前缀 
  public DataSource dataSource(){ 
    return DataSourceBuilder.create().build(); 
  } 
}

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

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

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

package com.chhliu.springcloud.config;  
import java.sql.SQLException; 
import javax.sql.DataSource; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.cloud.context.config.annotation.RefreshScope; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.Primary;  
import com.alibaba.druid.pool.DruidDataSource; 
import lombok.extern.slf4j.Slf4j; 
 
/** 
 * 
 * 描述:如果不使用代码手动初始化DataSource的话,监控界面的SQL监控会没有数据("是spring boot的bug???") 
 * @author chhliu 
 * 创建时间:2017年2月9日 下午7:33:08 
 * @version 1.2.0 
 */ 
@Slf4j 
@Configuration 
@RefreshScope 
public class DruidConfiguration { 
  @Value("${spring.datasource.url}") 
  private String dbUrl; 
  @Value("${spring.datasource.username}") 
  private String username; 
  @Value("${spring.datasource.password}") 
  private String password; 
  @Value("${spring.datasource.driverClassName}") 
  private String driverClassName; 
  @Value("${spring.datasource.initialSize}") 
  private int initialSize; 
  @Value("${spring.datasource.minIdle}") 
  private int minIdle; 
  @Value("${spring.datasource.maxActive}") 
  private int maxActive; 
  @Value("${spring.datasource.maxWait}") 
  private int maxWait; 
  @Value("${spring.datasource.timeBetweenEvictionRunsMillis}") 
  private int timeBetweenEvictionRunsMillis; 
  @Value("${spring.datasource.minEvictableIdleTimeMillis}") 
  private int minEvictableIdleTimeMillis; 
  @Value("${spring.datasource.validationQuery}") 
  private String validationQuery; 
  @Value("${spring.datasource.testWhileIdle}") 
  private boolean testWhileIdle; 
  @Value("${spring.datasource.testOnBorrow}") 
  private boolean testOnBorrow; 
  @Value("${spring.datasource.testOnReturn}") 
  private boolean testOnReturn; 
  @Value("${spring.datasource.poolPreparedStatements}") 
  private boolean poolPreparedStatements; 
  @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}") 
  private int maxPoolPreparedStatementPerConnectionSize; 
  @Value("${spring.datasource.filters}") 
  private String filters; 
  @Value("${spring.datasource.connectionProperties}") 
  private String connectionProperties; 
  @Value("${spring.datasource.useGlobalDataSourceStat}") 
  private boolean useGlobalDataSourceStat; 
 
  @Bean   //声明其为Bean实例 
  @Primary //在同样的DataSource中,首先使用被标注的DataSource 
  @RefreshScope 
  public DataSource dataSource(){ 
    DruidDataSource datasource = new DruidDataSource(); 
    datasource.setUrl(this.dbUrl); 
    datasource.setUsername(username); 
    datasource.setPassword(password); 
    datasource.setDriverClassName(driverClassName); 
 
    //configuration 
    datasource.setInitialSize(initialSize); 
    datasource.setMinIdle(minIdle); 
    datasource.setMaxActive(maxActive); 
    datasource.setMaxWait(maxWait); 
    datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); 
    datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); 
    datasource.setValidationQuery(validationQuery); 
    datasource.setTestWhileIdle(testWhileIdle); 
    datasource.setTestOnBorrow(testOnBorrow); 
    datasource.setTestOnReturn(testOnReturn); 
    datasource.setPoolPreparedStatements(poolPreparedStatements); 
    datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize); 
    datasource.setUseGlobalDataSourceStat(useGlobalDataSourceStat); 
    try { 
      datasource.setFilters(filters); 
    } catch (SQLException e) { 
      log.error("druid configuration initialization filter: "+ e); 
    } 
    datasource.setConnectionProperties(connectionProperties); 
    return datasource; 
  } 
}

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

从前面的博客中,我们不难发现,要想实现动态刷新,关键点就在post refresh的请求上,那我们就从刷新配置文件开始。
当我们post刷新请求的时候,这个请求会被actuator模块拦截,这点从启动的日志文件中就可以看出

复制代码 代码如下:


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

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

@ConfigurationProperties(prefix = "endpoints.refresh", ignoreUnknownFields = false) 
@ManagedResource 
public class RefreshEndpoint extends AbstractEndpoint<Collection<String>> { 
   private ContextRefresher contextRefresher; 
   public RefreshEndpoint(ContextRefresher contextRefresher) { 
    super("refresh"); 
    this.contextRefresher = contextRefresher; 
  }  
  @ManagedOperation 
  public String[] refresh() { 
    Set<String> keys = contextRefresher.refresh(); 
    return keys.toArray(new String[keys.size()]); 
  } 
   @Override 
  public Collection<String> invoke() { 
    return Arrays.asList(refresh()); 
  }  
}

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

private RefreshScope scope; 
   public ContextRefresher(ConfigurableApplicationContext context, RefreshScope scope) { 
    this.context = context; 
    this.scope = scope; 
  }  
  public synchronized Set<String> refresh() { 
    Map<String, Object> before = extract( 
        this.context.getEnvironment().getPropertySources());// 1、before,加载提取配置文件 
    addConfigFilesToEnvironment();// 2、将配置文件加载到环境中 
    Set<String> keys = changes(before, 
        extract(this.context.getEnvironment().getPropertySources())).keySet();// 3、替换原来环境变量中的值 
    this.context.publishEvent(new EnvironmentChangeEvent(keys));// 4、发布变更事件, 
    this.scope.refreshAll(); 
    return keys; 
  }

以上是“spring cloud config如何实现datasource热部署”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI