原创文章,转载请注明
spring cloud的一个子项目spring cloud config致力于为分布式系统提供一个配置中心,方便分布式系统进行配置文件的加载。实际上它满足了我们两个维度对配置文件的需求。第一个维度,不同系统集群间的统一和区别配置。第二个维度,开发,测试,生产环境的区别配置。借用网上一张图来表示:
另外,spring cloud支持git和svn,因此对于配置文件的管理还可以进行版本控制。
-
所需知识
开始进行总结之前,先必须具备一些知识点
git
git为目前很火的版本控制app,它有个很大的特点就是远程仓库。目前用的比较多的有https://github.com/,国内的有码云https://git.oschina.net
spring4
不论是spring boot还是spring cloud都是依赖于spring4进行的,如果还停留在spring3的话,可以先了解一下spring4 spring boot
spring boot 是spring cloud的基础,spring boot致力于快速构建web应用,而不需传统spring的各种配置,关键词是“约定(习惯)大于配置”
-
存在的坑
这里记录我在搭建过程中遇到的坑
java8
官方要求使用jdk8,虽然spring boot在jdk7中也能运行,但是这里和spring cloud集成的时候就出问题了,问题表现为在maven build的时候出现8194错误代码。因此以前用的myeclipse10是不能用了。myecplise2016是支持jdk8的,而且内置集成了对git的支持。
官方bug
目前最新版本的spring cloud为Camden.SR5,但是它在搭建客户端的时候,不能成功获取配置,官方文档也没有任何说明。因此估计是官方bug。这个问题很恶心,耽误了我好多时间。换成Brixton.RELEASE版本,spring boot的starter换成相应的1.3.5.RELEASE版本即可解决问题。
-
server端
server端所依赖的jar包,pom.xml如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.4.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- config -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
application.yml配置如下:
server:
port: 8888
spring:
cloud:
config:
server:
git:
uri: https://github.com/wulinfeng2/services.git
searchPaths: config
关键点有两个:1、端口设置,该端口和客户端不能相同。2、设置git的位置,如果你的配置文件不在根目录下,使用searchPath进行指定
额外知识点补充:从官方文档了解到,git的配置支持模板,可通过它,按照特定条件检索出配置文件。有兴趣的可以去了解一下
配置文件命名规则说明:
配置文件和url存在一定的关系,命名规则为{application}-{profile}-{label}
{application}——表示客户端的spring.application.name
{profile}——spring4的profile概念,表示客户端的spring.application.profiles.active
{label}——git中的分支,默认为master
如果不指定profile,那么对应{application}文件。
额外知识点补充:我们更多的时候是希望为不同环境生成统一的配置,还没有精确到单个项目。从官方文档可知,这种情况的命名为application-{profile}-{label}。application是一个约定,以application或application-*的配置适用于所有客户端。如果同时有匹配spring.application.name的配置文件存在,那么该客户端优先使用该应用名称的配置文件。
比如:我们的配置文件为有application-dev,application,userService-dev,userService这四个命名的文件。
如果客户端的spring.application.name=userService
spring.application.profiles.active=dev
则获得userService-dev文件
如果客户端的spring.application.name=userService
则获得userService文件
如果客户端的spring.application.name=user
spring.application.profiles.active=dev
则获得application-dev文件
如果客户端的spring.application.name=user
则获得application文件
配置文件名和url的映射关系:
url:{application}/{profile}/{label}
url:{application}-{profile}-{label}.yml
{application}-{profile}-{label}.propertites
最后来写我们的启动类
@SpringBootApplication
@EnableConfigServer
public class Application
{
public static void main( String[] args )
{
SpringApplication.run(Application.class, args);
}
}
关键代码为 @EnableConfigServer,该配置spring-cloud-config-server.jar包中的注释类。它默认会去进行git的配置。如果缺少该jar包,会报错为缺少eclipse.jgit中的SSHSessionFactory类。这个报错貌似eclipse缺少jgit插件,不能使用https连接git。实际是缺少spring的jar包。
这个时候我们的服务端就搭建OK了
检验服务是否就绪
启动服务,浏览器中输入以下地址,看看是否能读取到配置http://localhost:8888/userService/dev
可以看到name为{application},profiles为{profile},label为{label}。同时可以通过source看到其中的配置项
-
Client端
客户端不能用目前最新的版本,不然不能读取到配置。待官方解决,下个版本估计会解决此问题。也可能是我的使用不对,如果有谁知道,可以告知。
所以为了避开以上的坑,使用如下的依赖,pom.xml如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.5.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
bootstrap.yml配置如下:
spring:
application:
name: userService
cloud:
config:
uri: http://localhost:8888
profiles:
active: dev
注意application name如果和配置文件名的{application}匹配,则取该文件。否则为application或application-*文件
cloud.config.uri指明server端开放的地址
profiles.active指明{profile},同样通过匹配配置文件名来寻找配置文件,如果没有定义,则需找没有{profile}的配置文件
最后来看一下用来启动类
@SpringBootApplication
@RestController
@RefreshScope
public class Application
{
@Value("${my-config.version}")
private String version;
@Autowired
void setEnviroment(Environment env) {
System.out.println("env:"
+ env.getProperty("my-config.version"));
}
@RequestMapping("/test")
public String home() {
return "version is: " + this.version;
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
注意
@RefreshScope可以动态刷新配置
如果没有问题的话,将在控制台打印出配置文件中的my-config.version属性。
访问http://location:8080/test,界面会显示version is:配置文件中的my-config.version属性
补充知识点:官网还说道了可以通过/env来获得配置服务端的信息。比如访问http://location:8080/env地址,你会得到如下信息:
可以看到客户端的profiles,服务端开放的端口,实际配置文件的地址。
当然,要使用env需要依赖spring-boot-starter-actuator.jar