在软件开发中,少不了系统参数配置信息。通常我们会将信息写入配置文件中。但是如果有很多个服务或应用需要配置,并且每个服务还分为开发、测试、生产等不同维度的配置,那配置量还是很大的。当然,我们也可以将配置信息放入Redis、db、zookeeper等,然后开发一个管理界面进行管理。但是这无疑增加了额外的工作成本。

在spring cloud中,为我们提供了分布式配置管理功能,我们只需稍加配置即可使用。

使用spring cloud来实现分布式配置管理功能大致需要如下几步:
1、创建配置文件仓库
Spring cloud使用git或svn存放配置文件,默认情况下使用git,因此你需要安装git私服或者直接使用互联网上的github或者git.oschina,这里使用的git.oschina。
创建一个空的module,取名cloud-config-repo,另外创建2个配置文件,名字分别为cloud-config-dev.properties和cloud-config-test.properteis。
这两个文件分别对应开发环境和测试环境所需要的配置信息,配置信息如下:

1
2
3
4
5
6
mysqldb.datasource.url=jdbc\:mysql\://192.168.74.135\:3306/test?useUnicode\=true&characterEncoding\=utf-8
mysqldb.datasource.username=root
mysqldb.datasource.password=123456
logging.level.org.springframework.web:DEBUG

my.custom.message=Hello,This message is from cloud-config-repo!

如上,配置文件包含了mysql的数据库连接信息和一条自定义的message。

然后提交到git.oschina。

2、创建spring cloud配置服务器
配置服务器的作用是从远程git或svn仓库中提取配置信息,并提供rest接口给外部调用。这个功能是spring cloud提供的,我们只需引入相关的jar包,并稍微设置一下即可。

创建一个module,并取名为cloud-config-server。
在pom文件中增加配置服务器的相关依赖:

1
2
3
4
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>

application.properteis文件配置如下:

1
2
3
server.port=8888
spring.cloud.config.server.git.uri=https://gitee.com/qincd/springcloud-demos.git
spring.cloud.config.server.git.searchPaths=cloud-config-repo

其中server.port是配置当前web应用绑定8888端口,git.uri指定配置文件所在的git工程路径,searchPaths表示将搜索该文件夹下的配置文件(我们的配置文件放在springcloud-demos这个工程的cloud-config-repo文件夹下)

在spring boot应用启动类中增加@EnableConfigServer,激活该应用为配置文件服务器。

1
2
3
4
5
6
7
8
9
@SpringBootApplication
@EnableConfigServer
public class App
{
    public static void main( String[] args )
    {
        SpringApplication.run(App.class, args);
    }
}

然后启动cloud-config-server,浏览器输入http://127.0.0.1:8888/cloud-config-dev.properties,可以看到已经获取到配置信息,如图:

3、创建一个服务使用该远程配置
创建一个module,取名为cloud-config-client,来从cloud-config-server获取配置信息使用。

这里我们使用mysql的配置信息来获取用户的信息,以及显示自定义的1条消息。

相关依赖如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.45</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
</dependency>

在resources下新增bootstrap.properteis文件,

1
2
3
spring.cloud.config.uri=http://127.0.0.1:${config.port:8888}
spring.cloud.config.name=cloud-config
spring.cloud.config.profile=${config.profile:dev}

其中config.uri指定远程加载配置信息的地址,就是前面我们刚建立的配置管理服务器的地址,绑定端口8888,其中config.port:8888,表示如果在命令行提供了config.port参数,我们就用这个端口,否则就用8888端口。config.name表示配置文件名称,查看我们前面创建配置文件,是这个名称:
cloud-config-dev.properties
可以分成两部分: {application}- {profile}.properties

所以我们配置config.name为cloud-config,config.profile为dev,其中dev表示开发配置文件,配置文件仓库里还有一个测试环境的配置文件,切换该配置文件只需要将dev改为test即可,当然这个参数也可以由启动时命令行传入,如:
java -jar cloud-simple-service-1.0.0.jar –config.profile =test
此时应用就会加载测试环境下的配置信息。

application.properties:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
server.port=8080

#DB Configuration:
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = ${mysqldb.datasource.url}
spring.datasource.username = ${mysqldb.datasource.username}
spring.datasource.password = ${mysqldb.datasource.password}

#JPA Configuration:
spring.jpa.database=MySQL
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
#spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy
#spring.jpa.database=org.hibernate.dialect.MySQL5InnoDBDialect
#spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MYSQL5Dialect

数据库的一张user表数据如下:

定义一个实体类User

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Entity
@Table(name = "user")
public class User {
    @Column
    @Id
    private String id;
    @Column(name = "user_id")
    private String userId;
    @Column
    private String username;
    @Column
    private String password;
    @Column(name = "user_image")
    private String userImage;
    @Column
    private String name;
    @Column
    private String summary;
    @Column
    private String email;
    @Column
    private Long createdAt;
}

增加一个根据username获取用户想信息的方法:

1
2
3
4
@Repository
public interface UserDao extends CrudRepository<User,String> {
    User findByUsername(String username);
}

1
2
3
4
5
6
7
8
@Service
public class UserService {
    @Autowired
    private UserDao userDao;
    public User findByUsername(String username) {
        return userDao.findByUsername(username);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    @RequestMapping("/{username}")
    @ResponseBody
    public User findUserByUsername(@PathVariable String username) throws Exception {
        if (StringUtils.isEmpty(username)) {
            throw new Exception("参数不能为空!");
        }
        return userService.findByUsername(username);
    }
}

再增加一个获取自定义配置信息的Service

1
2
3
4
5
6
7
8
@Service
public class ConfigService {
    @Value("${my.custom.message}")
    private String msg;
    public String getCustomMsg() {
        return this.msg;
    }
}

OK,准备工作完毕!下面进行测试。

启动cloud-config-server和cloud-config-client应用。
1.数据库配置测试
浏览器输入http://127.0.0.1:8080/user/admin,结果如下:

可以看到获取到了用户信息,即说明已经使用了远程参考的数据库配置信息。

2.自定义消息测试
我们新建一个测试类来进行测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class AppTest 
{
    @Autowired
    private ConfigService configService;
    @Test
    public void testGetCustomMsg()
    {
        String msg = configService.getCustomMsg();
        assertNotNull(msg);
        System.out.println(msg);
    }
}

运行该测试类,执行结果如下:

说明已经获取到了远程参考中定义的自定义配置。

代码:https://gitee.com/qincd/springcloud-demos/

说明:本文参照使用spring cloud实现分布式配置管理进行测试。