原文发布于:http://www.gufeng.tech/ 谷风的我的主页git
SpringCloud的ConfigServer默认是持久化使用的是git。git有它自然的优点,好比多版本管理、分支管理、提交审核策略等等,可是若是相对其中存储的数据作细粒度的权限控制,就力不从心了。固然,也能够改变使用方式以适应这种特色,可是今天咱们要作的是将持久化从git迁移到MySQL上。spring
ConfigServer有个接口:org.springframework.cloud.config.server.environment.EnvironmentRepository,这个接口的实现类就是ConfigServer的用来查询配置信息的,方法签名以下:sql
Environment findOne(String application, String profile, String label);数据库
咱们能够实现这个接口,在方法实现中查询MySQL,由此看来,咱们已经成功一半了,另外一半就是解决如何把数据存到MySQL中。咱们仍是先解决查询的问题,咱们实现该方法内容以下:app
public class DatabasesEnvironmentRepository implements EnvironmentRepository { @Autowired private ConfigService configService; @Override public Environment findOne(String application, String profile, String label) { if (StringUtils.isEmpty(application) || StringUtils.isEmpty(profile)) return null; ConfigItem configItem = configService.findConfig(application, profile, label); if (configItem != null) { Environment environment = new Environment(application, StringUtils.commaDelimitedListToStringArray(profile), label, configItem.getVersion()); Map map = new HashMap<>(); for (ConfigProperty configProperty : configItem.getConfigProperties()) { map.put(configProperty.getKey(), configProperty.getValue()); } environment.add(new PropertySource(application + "_" + profile + "_" + label, map)); return environment; } return new Environment(application, StringUtils.commaDelimitedListToStringArray(profile)); } }
接下来咱们看一下ConfigService类的内容:ide
@Servicepublic class ConfigService { @Autowired private ConfigDAO configDAO; public ConfigItem findConfig(String application, String profile, String label) { ConfigItem configItem = configDAO.findConfig(application, profile, label); if (null == configItem) { return null; } List configProperties = configDAO.findConfigProperties(configItem.getId()); configItem.setConfigProperties(configProperties); return configItem; } }
最后咱们看一下ConfigDAO的实现:url
@Mapperpublic interface ConfigDAO { @Select("select * from config_item where application = #{application} and profile = #{profile} and label = #{label}") List findConfigProperties(@Param("application") String application, @Param("profile") String profile, @Param("label") String label); }
这里咱们使用的是MyBatis的注解方式,关于MyBatis的注解使用详细内容请查阅相关文档。orm
咱们首先看下数据源的配置:server
@Configurationpublic class DataSourceConfiguration { @Value("${jdbc.driver}") private String driver; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; @Value("${jdbc.maxActive}") private int maxActive; @Value("${jdbc.maxIdel}") private int maxIdel; @Value("${jdbc.maxWait}") private long maxWait; @Bean public BasicDataSource dataSource(){ BasicDataSource dataSource = new BasicDataSource(); dataSource.setDriverClassName(driver); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); dataSource.setMaxTotal(maxActive); dataSource.setMaxIdle(maxIdel); dataSource.setMaxWaitMillis(maxWait); dataSource.setValidationQuery("SELECT 1"); dataSource.setTestOnBorrow(true); return dataSource; } }
接下来看一下MyBatis的配置信息(固然,也可使用SpringJDBC来实现):接口
@Configuration @EnableTransactionManagement//支持事务
public class MyBatisConfig implements TransactionManagementConfigurer { @Autowired private DataSource dataSource; @Override public PlatformTransactionManager annotationDrivenTransactionManager() { return new DataSourceTransactionManager(dataSource); } @Bean(name = "sqlSessionFactory") public SqlSessionFactory sqlSessionFactoryBean() { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); try { return bean.getObject(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } @Bean public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) { return new SqlSessionTemplate(sqlSessionFactory); } }
最后看一下ConfigProperty中都有哪些内容呢?至少包括如下内容:application, profile, label, key, value,其它内容能够根据实际须要增减。
这里提供两种思路供参考:
一:在ConfigPropertity对应的表里存储当前使用的配置及历史配置,经过版本(或者状态位)加以区分,使用状态位的好处是总体存储数量会少一下,使用版本的好处是一下就可以查到某个历史版本的数据而不须要通过分析;
二:分两张表,一掌存储当前生效正在使用的配置信息,另外一张表用来存储历史配置信息,每次有变化时都同时写入两张表,历史表采用追加的方式,当前表采用更新的方式。
以上就是把ConfigServer的持久化存储从git改到MySQL的一种作法。