1 配置管理的架构
如图3-2所示,微服务启动到配置完成,发生了以下几件事情。
- 当一个微服务实例出现时,它将调用一个服务端点来读取其所在环境的特定配置信息。配置管理的连接信息(连接凭据、服务端点等)将在微服务启动时被传递给微服务。
- 实际的配置信息驻留在存储库中。基于配置存储库的实现,可以选择使用不同的实现来保存配置数据。配置存储库的实现选择可以包括源代码控制下的文件、关系数据库或键值数据存储。
- 应用程序配置数据的实际管理与应用程序的部署方式无关。配置管理的更改通常通过构建和部署管道来处理,其中配置的更改可以通过版本信息进行标记,并通过不同的环境进行部署。
- 进行配置管理更改时,必须通知使用该应用程序配置数据的服务,井刷新应用程序数据的副本。
下面介绍两种配置信息的存储方式:
1 Config Server从本地读取配置文件
本地仓库是指将所有的配置文件统一写在Config Server工程目录下。config server暴露Http API接口,config client通过调用config server的Http API接口来读取配置文件。
1.1 新建一个主maven项目
项目结构
pom.xml依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
</dependency>
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
1.2 在启动类加上@EnableConfigServer注解
该注解使服务成为Spring Cloud Config服务
@EnableConfigServer
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})
public class ConfigApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class, args);
}
}
1.3 配置文件application.yml
Spring Config Server的端口号8888,程序名config-server,profiles为native,配置信息存储文件所在的目录为classpath下的config目录。
server:
port: 8888
spring:
application:
name: config-server
profiles:
active: native
cloud:
config:
server:
native:
searchLocations: classpath:config
1.4 通过浏览器访问配置信息
文件(存储配置信息)路径已经在application.yml中配置了,但是文件名并没有指定,因此URL中要包括文件名。
1.5 构建Config Client
新建工程config-client,该工程作为Config Client从Config Server读取配置文件
pom.xml依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
1.6 配置文件bootstrap.yml
config client向Url地址为http://localhost:8888的Config Server读取配置文件。如果没有读取成功则执行快速失败(fail-fast),读取的是dev文件。配置文件中的变量{spring.application.name}和{spring.profiles.active},两者以 “-” 相连,构成了向Config Server读取的配置文件名,config-client-dev.yml。
spring:
application:
name: config-client
profiles:
active: dev
cloud:
config:
uri: http://localhost:8888
fail-fast: true
在config-client工程写一个API测试接口,读取配置文件的foo变量并返回。
@RefreshScope:由于Spring Boot只会在启动时读取Spring Cloud 中的属性配置,因此Spring Cloud配置服务器中的属性进行更改不会被Spring Boot应用程序自动获取。这个注解就是强制Spring Boot重新读取应用程序配置。
@RefreshScope
@RestController
public class MyController {
@Value("${foo:defaultname}")
String foo;
@RequestMapping("/foo")
public String hi(){
return foo;
}
}
启动工程config-server,再启动config-client,此时控制台会显示config-client向Url地址为http://localhost:8888的Config Server读取了配置文件,程序的启动端口为8888。
2 Config Server从远程Git仓库读取配置文件
2.1 修改Config Server的配置文件application.yml。
server:
port: 8888
spring:
application:
name: config-server-git
cloud:
config:
server:
git:
uri: https://github.com/TLR2019/foo
search-paths: configpassword
username: TLR2019
password: ********
uri为GitHub仓库的地址,search-paths为远程仓库中配置文件所在路径,username和password为GitHub仓库的登录名和密码,如果是私有的仓库登录名和密码是必须的,公开的仓库可以不需要,default-label为仓库的分支,本例是从master读取。
2.2 GitHub中的项目
2.3 客户端访问
3 使用Spring Cloud配置服务器连接数据源
3.1 数据源配置信息,config-datasource-dev.yml
连接的是Mysql数据库
datasource:
druid:
url: jdbc:mysql://localhost:3306/user?characterEncoding=utf-8
username: root
password: ******
driverClassName: com.mysql.jdbc.Driver
initialSize: 5 #初始建立连接数量
minIdle: 5 #最小连接数量
maxActive: 20 #最大连接数量
maxWait: 10000 #获取连接最大等待时间,毫秒
testOnBorrow: true #申请连接时检测连接是否有效
testOnReturn: false #归还连接时检测连接是否有效
timeBetweenEvictionRunsMillis: 60000 #配置间隔检测连接是否有效的时间(单位是毫秒)
minEvictableIdleTimeMillis: 300000 #连接在连接池的最小生存时间(毫秒)
3.2 客户端编写
客户端主要是通过读取的数据源往数据库中写入数据
3.2.1 项目结构
3.2.2 创建model,dao,controller,service
model:lombok的@Data和@ToString注解表示get set方法和tostring方法
@Entity
@Table(name="user")
@Data
@@ToString
public class User {
@Id
private String id;
private String name;
private String password;
}
dao:使用Spring Data Jpa操作数据库
public interface UserRepository extends JpaRepository<User, String> {
}
service:
@Service
public class UserService {
@Autowired
UserRepository userRepository;
//为了简单,我们就不返回json了
@Transactional
public void save(User user) {
userRepository.save(user);
}
}
controller:
@RefreshScope
@RestController
@RequestMapping("/user/")
public class UserController implements UserControllerApi {
@Autowired
UserService userService;
@RequestMapping("/save")
public String saveUser(User user){
userService.save(user);
return "user";
}
}
为了方便测试,我们使用Swagger。
@Api(value = "修改用户信息", description = "用户信息接口")
public interface UserControllerApi {
@ApiOperation("保存用户信息")
String saveUser(User user);
}
3.2.3 使用Swagger测试
4 保护敏感配置信息
4.1 配置环境
JDK8的版本,首先需要下载Oracle JCE(不限长度的Java加密扩展)来替换默认的,替换java Home路径下的jre\lib\security的文件。
4.2 配置config
在bootstrap.yml文件中配置密钥。一定要是bootstrap.yml,使用其他名字的配置文件会报错。
encrypt:
key: 1234
启动config Server,启动后可以看到暴露/encrypt和/decrypt接口。
4.3 加密获得密文
使用postman进行测试,输入http://localhost:8888/encrypt/,选择post提交方式,在body中选择raw格式,并选择test格式,如图。
4.4 将密文写到github文件
注意:密文前面要加{cipher}
4.5 读取解密后的信息
Spring Cloud知道我们的秘钥,因此可以自动解析。