如何基于 JGit 方式实现分布式配置中心 config 的配置仓库?
《配置中心 Spring Cloud Config 详解》系列文章更新,一起在技术的路上精进!本系列文章将会介绍Spring Cloud 中提供了分布式配置中心Spring Cloud Config。应用服务中除了实现系统功能的代码,还需要连接资源和其它应用,经常有很多需要在外部配置的数据去调整应用的行为,如切换不同的数据库,设置功能开关等。随着微服务的不断增加,需要系统具备可伸缩和可扩展性,除此之外就是管理相当多的服务实例的配置数据。在应用的开发阶段由各个服务自治,但是到了生产环境之后会给运维带来很大的麻烦,特别是微服务的规模比较大,配置的更新更为麻烦。为此,系统需要建立一个统一的配置管理中心。
在前面的文章,我们介绍了配置服务器实现中的 EnvironmentRepository 接口和 SearchPathLocator 接口。以及 JGit 方式实现配置仓库的相关接口定义,本文将会具体介绍 JGit 方式实现配置仓库。
JGit 方式实现配置仓库
根据前面一篇文章的介绍,我们知道远端仓库的地址URI、用户名、密码等属性,在使用git仓库时都需要配置的。还有一些属性,如basedir(即本地拷贝之后的工作仓库地址)和passphrase(即SSH的私钥)等,也都是我们在环境仓库进行设置时可选项。
JGitEnvironmentRepository继承自抽象类AbstractScmEnvironmentRepository,而该抽象类又继承自AbstractScmAccessor,AbstractScmAccessor是SCM(软件配置管理,source control management)实现的父类,定义了基础的属性组成以获取SCM的资源。我们从基类AbstractScmAccessor看起,基类中定义了SCM的配置属性和基本方法。
在抽象类AbstractScmEnvironmentRepository
中,我们看一下实现EnvironmentRepository
接口中的获取配置信息的方法。
public synchronized Environment findOne(String application, String profile, String label) {
NativeEnvironmentRepository delegate = new NativeEnvironmentRepository(getEnvironment(),
new NativeEnvironmentProperties());
Locations locations = getLocations(application, profile, label);
delegate.setSearchLocations(locations.getLocations());
Environment result = delegate.findOne(application, profile, "");
result.setVersion(locations.getVersion());
result.setLabel(label);
return this.cleaner.clean(result, getWorkingDirectory().toURI().toString(),
getUri());
}
在获取应用服务的配置信息时,新建了一个本地的环境仓库,作为代理的环境仓库,synchronized关键字保证每次只有一个线程操作环境仓库。首先是获取本地仓库中,指定应用的位置(一般是一个tmp目录,也可以自行指定);在获取到本地的搜索路径之后,将会根据该路径搜索对应应用的配置信息;最后将得到的结果进行处理,设置应用的profile和标签等。由于#delegate.findOne
返回的Environment对象会包含workingDir和json key的相关信息,所以这里还调用了EnvironmentCleaner
的clean方法,将结果进行处理。
该抽象类基于SCM对配置信息进行管理的子类为JGitEnvironmentRepository
。下面具体讲解JGit中实现的方法。
public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
implements EnvironmentRepository, SearchPathLocator, InitializingBean {
// HTTP or SSH 连接的超时时间.
private int timeout = 5;
// 标记是否在启动时克隆仓库
private boolean cloneOnStart = false;
private boolean forcePull;
private boolean initialized;
//标记是否删除本地的分支删除,如果它的原始分支已被删除。
private boolean deleteUntrackedBranches;
public JGitEnvironmentRepository(ConfigurableEnvironment environment, JGitEnvironmentProperties properties) {
super(environment, properties);
this.cloneOnStart = properties.isCloneOnStart();
this.defaultLabel = properties.getDefaultLabel();
this.forcePull = properties.isForcePull();
this.timeout = properties.getTimeout();
this.deleteUntrackedBranches = properties.isDeleteUntrackedBranches();
}
public String refresh(String label) {
//...
//调用git操作的方法,准备好工作目录,返回最新的HEAD版本号
}
@Override
public synchronized Locations getLocations(String application, String profile, String label) {
if (label == null) {
label = this.defaultLabel;
}
String version = refresh(label);
return new Locations(application, profile, label, version,
getSearchLocations(getWorkingDirectory(), application, profile, label));
}
//...
}
JGitEnvironmentRepository
继承抽象类AbstractScmEnvironmentRepository
,在SCM的基础上加入了git操作相关的方法。获取具体的配置文件地址时,需要传入应用名、profile和标签信息,根据最新的版本号,最后返回Locations定位到资源的搜索路径。#refresh
方法用于刷新本地仓库的配置状态,保证每次都能拉取到最新的配置信息。
小结
本文主要接着 Spring Cloud Config 服务端 Config Server EnvironmentRepository接口和SearchPathLocator接口的实现之上,具体介绍其中 JGit 方式实现配置仓库服务端存储相关定义,接下来将会重点介绍 JGit 获取最新的远端仓库配置的实现。
- 点赞
- 收藏
- 关注作者
评论(0)